summaryrefslogtreecommitdiffstats
path: root/shlibs
diff options
context:
space:
mode:
authorKarel Zak2009-05-14 15:38:50 +0200
committerKarel Zak2009-05-14 15:38:50 +0200
commit40672152dcbd17ce41aa3f6670f9898402990a5c (patch)
treec1dc5fd25ee81ed8d7e86034c8aa19731db6d24d /shlibs
parentblkid: make libuuid optional (diff)
downloadkernel-qcow2-util-linux-40672152dcbd17ce41aa3f6670f9898402990a5c.tar.gz
kernel-qcow2-util-linux-40672152dcbd17ce41aa3f6670f9898402990a5c.tar.xz
kernel-qcow2-util-linux-40672152dcbd17ce41aa3f6670f9898402990a5c.zip
build-sys: rename /libs to /shlibs
On Wed, May 13, 2009 at 05:38:49AM -0400, Christoph Hellwig wrote: > Also the lib vs libs toplevel directories probably aren't a too good > choice. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs')
-rw-r--r--shlibs/Makefile.am5
-rw-r--r--shlibs/blkid/.gitignore4
-rw-r--r--shlibs/blkid/COPYING.libblkid510
-rw-r--r--shlibs/blkid/Makefile.am12
-rw-r--r--shlibs/blkid/README.blkid78
-rw-r--r--shlibs/blkid/TODO54
-rw-r--r--shlibs/blkid/bin/Makefile.am15
-rw-r--r--shlibs/blkid/bin/blkid.8211
-rw-r--r--shlibs/blkid/bin/blkid.c633
-rw-r--r--shlibs/blkid/bin/blkid.sh.in10
-rw-r--r--shlibs/blkid/bin/findfs.835
-rw-r--r--shlibs/blkid/bin/findfs.c60
-rw-r--r--shlibs/blkid/bin/findfs.sh.in10
-rw-r--r--shlibs/blkid/blkid.pc.in11
-rw-r--r--shlibs/blkid/libblkid.381
-rw-r--r--shlibs/blkid/src/Makefile.am45
-rw-r--r--shlibs/blkid/src/blkid.h171
-rw-r--r--shlibs/blkid/src/blkid.sym68
-rw-r--r--shlibs/blkid/src/blkidP.h343
-rw-r--r--shlibs/blkid/src/cache.c243
-rw-r--r--shlibs/blkid/src/config.c205
-rw-r--r--shlibs/blkid/src/dev.c255
-rw-r--r--shlibs/blkid/src/devname.c558
-rw-r--r--shlibs/blkid/src/devno.c228
-rw-r--r--shlibs/blkid/src/encode.c288
-rw-r--r--shlibs/blkid/src/evaluate.c264
-rw-r--r--shlibs/blkid/src/getsize.c207
-rw-r--r--shlibs/blkid/src/list.h179
-rw-r--r--shlibs/blkid/src/llseek.c142
-rw-r--r--shlibs/blkid/src/probe.c919
-rw-r--r--shlibs/blkid/src/probers/Makefile.am43
-rw-r--r--shlibs/blkid/src/probers/adaptec_raid.c107
-rw-r--r--shlibs/blkid/src/probers/btrfs.c92
-rw-r--r--shlibs/blkid/src/probers/cramfs.c62
-rw-r--r--shlibs/blkid/src/probers/ddf_raid.c74
-rw-r--r--shlibs/blkid/src/probers/ext.c571
-rw-r--r--shlibs/blkid/src/probers/gfs.c129
-rw-r--r--shlibs/blkid/src/probers/hfs.c313
-rw-r--r--shlibs/blkid/src/probers/highpoint_raid.c64
-rw-r--r--shlibs/blkid/src/probers/hpfs.c122
-rw-r--r--shlibs/blkid/src/probers/iso9660.c133
-rw-r--r--shlibs/blkid/src/probers/isw_raid.c60
-rw-r--r--shlibs/blkid/src/probers/jfs.c70
-rw-r--r--shlibs/blkid/src/probers/jmicron_raid.c59
-rw-r--r--shlibs/blkid/src/probers/linux_raid.c167
-rw-r--r--shlibs/blkid/src/probers/lsi_raid.c55
-rw-r--r--shlibs/blkid/src/probers/luks.c66
-rw-r--r--shlibs/blkid/src/probers/lvm.c133
-rw-r--r--shlibs/blkid/src/probers/minix.c51
-rw-r--r--shlibs/blkid/src/probers/netware.c97
-rw-r--r--shlibs/blkid/src/probers/ntfs.c184
-rw-r--r--shlibs/blkid/src/probers/nvidia_raid.c60
-rw-r--r--shlibs/blkid/src/probers/ocfs.c210
-rw-r--r--shlibs/blkid/src/probers/probers.h60
-rw-r--r--shlibs/blkid/src/probers/promise_raid.c63
-rw-r--r--shlibs/blkid/src/probers/reiserfs.c126
-rw-r--r--shlibs/blkid/src/probers/romfs.c51
-rw-r--r--shlibs/blkid/src/probers/silicon_raid.c77
-rw-r--r--shlibs/blkid/src/probers/squashfs.c68
-rw-r--r--shlibs/blkid/src/probers/swap.c149
-rw-r--r--shlibs/blkid/src/probers/sysv.c141
-rw-r--r--shlibs/blkid/src/probers/udf.c159
-rw-r--r--shlibs/blkid/src/probers/ufs.c225
-rw-r--r--shlibs/blkid/src/probers/vfat.c364
-rw-r--r--shlibs/blkid/src/probers/via_raid.c82
-rw-r--r--shlibs/blkid/src/probers/vxfs.c41
-rw-r--r--shlibs/blkid/src/probers/xfs.c63
-rw-r--r--shlibs/blkid/src/probers/zfs.c66
-rw-r--r--shlibs/blkid/src/read.c492
-rw-r--r--shlibs/blkid/src/resolve.c139
-rw-r--r--shlibs/blkid/src/save.c193
-rw-r--r--shlibs/blkid/src/tag.c474
-rw-r--r--shlibs/blkid/src/tst_types.c63
-rw-r--r--shlibs/blkid/src/verify.c200
-rw-r--r--shlibs/blkid/src/version.c56
75 files changed, 12118 insertions, 0 deletions
diff --git a/shlibs/Makefile.am b/shlibs/Makefile.am
new file mode 100644
index 000000000..e09828e6c
--- /dev/null
+++ b/shlibs/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS =
+
+if BUILD_LIBBLKID
+SUBDIRS += blkid
+endif
diff --git a/shlibs/blkid/.gitignore b/shlibs/blkid/.gitignore
new file mode 100644
index 000000000..d6126deab
--- /dev/null
+++ b/shlibs/blkid/.gitignore
@@ -0,0 +1,4 @@
+*.sh
+bin/blkid
+bin/findfs
+test_*
diff --git a/shlibs/blkid/COPYING.libblkid b/shlibs/blkid/COPYING.libblkid
new file mode 100644
index 000000000..cf9b6b997
--- /dev/null
+++ b/shlibs/blkid/COPYING.libblkid
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+^L
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+^L
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/shlibs/blkid/Makefile.am b/shlibs/blkid/Makefile.am
new file mode 100644
index 000000000..a27c85248
--- /dev/null
+++ b/shlibs/blkid/Makefile.am
@@ -0,0 +1,12 @@
+include $(top_srcdir)/config/include-Makefile.am
+
+SUBDIRS = src bin
+
+# pkg-config stuff
+pkgconfigdir = $(usrlibexecdir)/pkgconfig
+pkgconfig_DATA = blkid.pc
+
+dist_man_MANS = libblkid.3
+
+EXTRA_DIST = README.blkid blkid.pc blkid.pc.in libblkid.3
+
diff --git a/shlibs/blkid/README.blkid b/shlibs/blkid/README.blkid
new file mode 100644
index 000000000..4fa9be1f7
--- /dev/null
+++ b/shlibs/blkid/README.blkid
@@ -0,0 +1,78 @@
+libblkid - a library to handle device identification and token extraction
+
+Basic usage is as follows - there are two normal usage patterns:
+
+For cases where a program wants information about multiple devices, or
+expects to be doing multiple token searches, the program should
+directly initialize cache file via (second parameter is cache
+filename, NULL = default):
+
+ blkid_cache cache = NULL;
+ if (blkid_get_cache(&cache, NULL) < 0)
+ /* error reading the cache file, not really fatal */
+
+Note that if no cache file exists, an empty cache struct is still
+allocated. Usage of libblkid functions will use the cache to avoid
+needless device scans.
+
+The model of the blkid cache is that each device has a number of
+attributes that can be associated with it. Currently the attributes
+which are supported (and set) by blkid are:
+
+ TYPE filesystem type
+ UUID filesystem uuid
+ LABEL filesystem label
+
+
+How to use libblkid? Normally, you either want to find a device with
+a specific NAME=value token, or you want to output token(s) from a
+device. To find a device that matches a following attribute, you
+simply call the blkid_get_devname() function:
+
+ if ((devname = blkid_get_devname(cache, attribute_name, value))) {
+ /* do something with devname */
+ string_free(devname);
+ }
+
+The cache parameter is optional; if it is NULL, then the blkid library
+will load the default blkid.tab cache file, and then release the cache
+before function call returns. The return value is an allocated string
+which holds the resulting device name (if it is found). If the value
+is NULL, then attribute_name is parsed as if it were
+"<attribute_name>=<value>"; if it cannot be so parsed, then the
+original attribute_name is returned in a copied allocated string.
+This is a convenience to allow user programs to want to translate user
+input, whether it is of the form: "/dev/hda1", "LABEL=root",
+"UUID=082D-26E3", and get back a device name that it can use.
+
+Alternatively, of course, the programmer can pass an attribute name of
+"LABEL", and value of "root", if that is more convenient.
+
+Another common usage is to retrieve the value of a specific attribute
+for a particular device. This can be used to determine the filesystem
+type, or label, or uuid for a particular device:
+
+ if ((value = blkid_get_tag_value(cache, attribute_name, devname))) {
+ /* do something with value */
+ string_free(value);
+ }
+
+If a program needs to call multiple blkid functions, then passing in a
+cache value of NULL is not recommended, since the /etc/blkid.tab file
+will be repeatedly parsed over and over again, with memory allocated
+and deallocated. To initialize the blkid cache, blkid_get_cache()
+function is used:
+
+ if (blkid_get_cache(&cache, NULL) < 0)
+ goto errout;
+
+The second parameter of blkid_get_cache (if non-zero) is the alternate
+filename of the blkid cache file (where the default is
+/etc/blkid.tab). Normally, programs should just pass in NULL.
+
+If you have called blkid_get_cache(), you should call blkid_put_cache()
+when you are done using the blkid library functions. This will save the
+cache to the blkid.tab file, if you have write access to the file. It
+will also free all associated devices and tags:
+
+ blkid_put_cache(cache);
diff --git a/shlibs/blkid/TODO b/shlibs/blkid/TODO
new file mode 100644
index 000000000..1d0a67eea
--- /dev/null
+++ b/shlibs/blkid/TODO
@@ -0,0 +1,54 @@
+
+ TODO
+ ----
+
+ - add command line interface for blkid_probe_filter_types():
+
+ # blkid -p -o udev --filter-type nofat
+
+ - (?) we need to ignore cache and config files when the files are writable
+ for non-root users and the library is linked with suid programs
+
+ - add -<BE|LE> suffix to test images for native-endian filesystems (e.g. swap)
+ and add support for such functionality to tests/ts/blkid/low-probe
+
+ - do we really need to depend on libuuid? Maybe the default should be
+ use in-tree code rather and link against libuuid -- especially when we
+ need it for uuid_unparse() only.
+
+ - consolidate "getsize" stuff (see getsize.c and lib/blkdev.c)
+
+ - cleanup __attribute__ usage
+
+ - add stripe size / alignment retrival support to libbkid for use
+ with mkfs. This would allow to deprecate libdisk from xfsprogs (1)
+ in favour of a common libblkid.
+
+ [ -- Christoph Hellwig, 16 Feb 2009 ]
+ (1) http://git.kernel.org/?p=fs/xfs/xfsprogs-dev.git;a=tree;f=libdisk;
+
+ [ .. or move whole libdisk to util-linux-ng and merge partx code to the
+ library -- kzak ]
+
+ - use /sys/block/<devname>/dm/name rather than scan /dev/mapper/ for the name
+ (see devname.c: probe_one()). The sysfs entry has been introduced by kernel
+ patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128.
+
+ - in lib/fsprobe.c wrapper use blkid_parse_tag_string() rather than a local
+ parser implementation
+
+ - use fstatat() in blkid__scan_dir()
+
+ - add evaluate.c: blkid_evaluate_tag_to_buffer() (and add lib/canonicalize.c:
+ canonicalize_path_to_buffer())
+
+ - add values:
+
+ FSSIZE -- filesystem size (klibc requirement)
+
+ SBOFFSET -- superblock offset; offset where SB was detected
+ (swapon requirement to check details from swap header)
+
+ MAGIC -- magic string
+ MAGICLEN -- length of magic string
+
diff --git a/shlibs/blkid/bin/Makefile.am b/shlibs/blkid/bin/Makefile.am
new file mode 100644
index 000000000..ff992ace6
--- /dev/null
+++ b/shlibs/blkid/bin/Makefile.am
@@ -0,0 +1,15 @@
+include $(top_srcdir)/config/include-Makefile.am
+
+AM_CPPFLAGS += -I$(ul_libblkid_srcdir)
+AM_LDFLAGS += $(ul_libblkid_la)
+
+sbin_PROGRAMS = blkid findfs
+dist_man_MANS = blkid.8 findfs.8
+
+if HAVE_STATIC_BLKID
+sbin_PROGRAMS += blkid.static
+blkid_static_SOURCES = $(blkid_SOURCES)
+blkid_static_LDFLAGS = "-all-static" # libtool option
+blkid_static_LDADD = $(ul_libblkid_la)
+blkid_static_CFLAGS = -I$(ul_libblkid_srcdir)
+endif
diff --git a/shlibs/blkid/bin/blkid.8 b/shlibs/blkid/bin/blkid.8
new file mode 100644
index 000000000..ff8e8e570
--- /dev/null
+++ b/shlibs/blkid/bin/blkid.8
@@ -0,0 +1,211 @@
+.\" Copyright 2000 Andreas Dilger (adilger@turbolinux.com)
+.\"
+.\" This man page was created for blkid from e2fsprogs-1.25.
+.\"
+.\" This file may be copied under the terms of the GNU Public License.
+.\"
+.\" Based on uuidgen, Mon Sep 17 10:42:12 2000, Andreas Dilger
+.TH BLKID 8 "February 2009" "Linux" "MAINTENANCE COMMANDS"
+.SH NAME
+blkid \- command\-line utility to locate/print block device attributes
+.SH SYNOPSIS
+.B blkid
+.RB \-L
+.IR label " | "
+.RB \-U
+.IR uuid
+
+.B blkid
+.RB [ \-ghlv ]
+.RB [ \-c
+.IR file ]
+.RB [ \-w
+.IR file ]
+.RB [ \-o
+.IR format ]
+.in +6
+.RB [ \-s
+.IR tag ]
+.RB [ \-t
+.IR NAME=value ]
+.I device
+[\fIdevice\fR ...]
+.in -6
+
+.B blkid
+.RB -p
+.RB [ \-O
+.IR offset ]
+.RB [ \-S
+.IR size ]
+.RB [ \-o
+.IR format ]
+.RB [ \-u
+.IR list ]
+.I device
+[\fIdevice\fR ...]
+
+.SH DESCRIPTION
+The
+.B blkid
+program is the command-line interface to working with
+.BR libblkid (3)
+library. It can determine the type of content (e.g. filesystem, swap)
+a block device holds, and also attributes (tokens, NAME=value pairs)
+from the content metadata (e.g. LABEL or UUID fields).
+.PP
+.B blkid
+has two main forms of operation: either searching for a device with a
+specific NAME=value pair, or displaying NAME=value pairs for one or
+more devices.
+.SH OPTIONS
+.TP
+.BI \-c " cachefile"
+Read from
+.I cachefile
+instead of reading from the default cache file
+.IR /etc/blkid.tab .
+If you want to start with a clean cache (i.e. don't report devices previously
+scanned but not necessarily available at this time), specify
+.IR /dev/null .
+.TP
+.B \-g
+Perform a garbage collection pass on the blkid cache to remove
+devices which no longer exist.
+.TP
+.B \-h
+Display a usage message and exit.
+.TP
+.B \-l
+Look up one device that matches the search parameter specified using
+the
+.B \-t
+option. If there are multiple devices that match the specified search
+parameter, then the device with the highest priority is returned, and/or
+the first device found at a given priority. Device types in order of
+decreasing priority are Device Mapper, EVMS, LVM, MD, and finally regular
+block devices. If this option is not specified,
+.B blkid
+will print all of the devices that match the search parameter.
+.TP
+.B \-L " label "
+Look up one device that uses the label (same as: -l -o device -t
+LABEL=<label>). This look up method is able to reliable use /dev/disk/by-label
+udev symlinks (depends on setting in /etc/blkid.conf). Avoid to use the
+symlinks directly. It is not reliable to use the symlinks without verification.
+The \fB-L\fR option is portable and works on systems with and without udev.
+.TP
+.B \-u " list "
+Restrict probing functions to defined (comma separated) list of "usage" types.
+Supported usage types are: filesystem, raid, crypto and other. The list can be
+prefixed with "no" to specify the usage types which should be ignored. For example:
+.sp
+ blkid -p -u filesystem,other /dev/sda1
+.sp
+probes for all filesystems and others (e.g. swap) formats, and
+.sp
+ blkid -p -u noraid /dev/sda1
+.sp
+probes for all supported formats exclude RAIDs. This option is useful with
+\fB-p\fR only.
+.TP
+.B \-U " uuid "
+Look up one device that uses the uuid. For more details see the \fB-L\fR option.
+.TP
+.BI \-o " format"
+Display
+.BR blkid 's
+output using the specified format. The
+.I format
+parameter may be:
+.RS
+.TP
+.B full
+print all tags (the default)
+.TP
+.B value
+print the value of the tags
+.TP
+.B list
+print the devices in a user-friendly format
+.TP
+.B device
+print the device name only
+.TP
+.B udev
+vol_id compatible mode; usable in udev rules
+.RE
+.TP
+.BI \-O " bytes"
+Probe at the given offset (only useful with \fB-p\fR).
+.TP
+.BI \-p
+Switch to low-level probing mode (bypass cache)"
+.TP
+.BI \-s " tag"
+For each (specified) device, show only the tags that match
+.IR tag .
+It is possible to specify multiple
+.B \-s
+options. If no tag is specified, then all tokens are shown for all
+(specified) devices.
+In order to just refresh the cache without showing any tokens, use
+.B "-s none"
+with no other options.
+.TP
+.BI \-S " bytes"
+Overwrite device/file size (only useful with \fB-p\fR).
+.TP
+.BI \-t " NAME" = "value"
+Search for block devices with tokens named
+.I NAME
+that have the value
+.IR value ,
+and display any devices which are found.
+Common values for
+.I NAME
+include
+.BR TYPE ,
+.BR LABEL ,
+and
+.BR UUID .
+If there are no devices specified on the command line, all block devices
+will be searched; otherwise only the specified devices are searched.
+.TP
+.B \-v
+Display version number and exit.
+.TP
+.BI \-w " writecachefile"
+Write the device cache to
+.I writecachefile
+instead of writing it to the default cache file
+.IR /etc/blkid.tab .
+If you don't want to save the cache to the default file, specify
+.IR /dev/null.
+If not specified it will be the same file as that given by the
+.B \-c
+option.
+.TP
+.I device
+Display tokens from only the specified device. It is possible to
+give multiple
+.I device
+options on the command line. If none is given, all devices which
+appear in
+.I /proc/partitions
+are shown, if they are recognized.
+.SH "RETURN CODE"
+If the specified token was found, or if any tags were shown from (specified)
+devices, 0 is returned. If the specified token was not found, or no
+(specified) devices could be identified, an exit code of 2 is returned.
+For usage or other errors, an exit code of 4 is returned.
+.SH AUTHOR
+.B blkid
+was written by Andreas Dilger for libblkid and improved by Theodore Ts'o
+and Karel Zak.
+.SH AVAILABILITY
+The blkid command is part of the util-linux-ng package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+.SH "SEE ALSO"
+.BR libblkid (3)
+.BR findfs (8)
diff --git a/shlibs/blkid/bin/blkid.c b/shlibs/blkid/bin/blkid.c
new file mode 100644
index 000000000..528e4a222
--- /dev/null
+++ b/shlibs/blkid/bin/blkid.c
@@ -0,0 +1,633 @@
+/*
+ * blkid.c - User command-line interface for libblkid
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#ifdef HAVE_TERMIO_H
+#include <termio.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern int getopt(int argc, char * const argv[], const char *optstring);
+extern char *optarg;
+extern int optind;
+#endif
+
+#define OUTPUT_VALUE_ONLY 0x0001
+#define OUTPUT_DEVICE_ONLY 0x0002
+#define OUTPUT_PRETTY_LIST 0x0004
+#define OUTPUT_UDEV_LIST 0x0008
+
+#include <blkid.h>
+
+const char *progname = "blkid";
+
+static void print_version(FILE *out)
+{
+ fprintf(out, "%s from %s (libblkid %s, %s)\n",
+ progname, PACKAGE_STRING, LIBBLKID_VERSION, LIBBLKID_DATE);
+}
+
+static void usage(int error)
+{
+ FILE *out = error ? stderr : stdout;
+
+ print_version(out);
+ fprintf(out,
+ "Usage:\n"
+ " %1$s -L <label> | -U <uuid>\n\n"
+ " %1$s [-c <file>] [-ghlLv] [-o format] [-s <tag>] \n"
+ " [-t <token>] [-w <file>] [dev ...]\n\n"
+ " %1$s -p [-O <offset>] [-S <size>] [-o format] <dev> [dev ...]\n\n"
+ "Options:\n"
+ " -c <file> cache file (default: /etc/blkid.tab, /dev/null = none)\n"
+ " -h print this usage message and exit\n"
+ " -g garbage collect the blkid cache\n"
+ " -o <format> output format; can be one of:\n"
+ " value, device, list, udev or full; (default: full)\n"
+ " -s <tag> show specified tag(s) (default show all tags)\n"
+ " -t <token> find device with a specific token (NAME=value pair)\n"
+ " -l lookup the the first device with arguments specified by -t\n"
+ " -L <label> convert LABEL to device name\n"
+ " -U <uuid> convert UUID to device name\n"
+ " -v print version and exit\n"
+ " -w <file> write cache to different file (/dev/null = no write)\n"
+ " <dev> specify device(s) to probe (default: all devices)\n\n"
+ "Low-level probing options:\n"
+ " -p switch to low-level mode (bypass cache)\n"
+ " -S <bytes> overwrite device size\n"
+ " -O <bytes> probe at the given offset\n"
+ " -u <list> filter by \"usage\" (e.g. -u filesystem,raid)\n"
+ "\n",
+ progname);
+
+ exit(error);
+}
+
+/*
+ * This function does "safe" printing. It will convert non-printable
+ * ASCII characters using '^' and M- notation.
+ */
+static void safe_print(const char *cp, int len)
+{
+ unsigned char ch;
+
+ if (len < 0)
+ len = strlen(cp);
+
+ while (len--) {
+ ch = *cp++;
+ if (ch > 128) {
+ fputs("M-", stdout);
+ ch -= 128;
+ }
+ if ((ch < 32) || (ch == 0x7f)) {
+ fputc('^', stdout);
+ ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
+ }
+ fputc(ch, stdout);
+ }
+}
+
+static int get_terminal_width(void)
+{
+#ifdef TIOCGSIZE
+ struct ttysize t_win;
+#endif
+#ifdef TIOCGWINSZ
+ struct winsize w_win;
+#endif
+ const char *cp;
+
+#ifdef TIOCGSIZE
+ if (ioctl (0, TIOCGSIZE, &t_win) == 0)
+ return (t_win.ts_cols);
+#endif
+#ifdef TIOCGWINSZ
+ if (ioctl (0, TIOCGWINSZ, &w_win) == 0)
+ return (w_win.ws_col);
+#endif
+ cp = getenv("COLUMNS");
+ if (cp)
+ return strtol(cp, NULL, 10);
+ return 80;
+}
+
+static int pretty_print_word(const char *str, int max_len,
+ int left_len, int overflow_nl)
+{
+ int len = strlen(str) + left_len;
+ int ret = 0;
+
+ fputs(str, stdout);
+ if (overflow_nl && len > max_len) {
+ fputc('\n', stdout);
+ len = 0;
+ } else if (len > max_len)
+ ret = len - max_len;
+ do
+ fputc(' ', stdout);
+ while (len++ < max_len);
+ return ret;
+}
+
+static void pretty_print_line(const char *device, const char *fs_type,
+ const char *label, const char *mtpt,
+ const char *uuid)
+{
+ static int device_len = 10, fs_type_len = 7;
+ static int label_len = 8, mtpt_len = 14;
+ static int term_width = -1;
+ int len, w;
+
+ if (term_width < 0)
+ term_width = get_terminal_width();
+
+ if (term_width > 80) {
+ term_width -= 80;
+ w = term_width / 10;
+ if (w > 8)
+ w = 8;
+ term_width -= 2*w;
+ label_len += w;
+ fs_type_len += w;
+ w = term_width/2;
+ device_len += w;
+ mtpt_len +=w;
+ }
+
+ len = pretty_print_word(device, device_len, 0, 1);
+ len = pretty_print_word(fs_type, fs_type_len, len, 0);
+ len = pretty_print_word(label, label_len, len, 0);
+ len = pretty_print_word(mtpt, mtpt_len, len, 0);
+ fputs(uuid, stdout);
+ fputc('\n', stdout);
+}
+
+static void pretty_print_dev(blkid_dev dev)
+{
+ fprintf(stderr, "pretty print not implemented yet\n");
+
+#ifdef NOT_IMPLEMENTED
+ blkid_tag_iterate iter;
+ const char *type, *value, *devname;
+ const char *uuid = "", *fs_type = "", *label = "";
+ char *cp;
+ int len, mount_flags;
+ char mtpt[80];
+ errcode_t retval;
+
+ if (dev == NULL) {
+ pretty_print_line("device", "fs_type", "label",
+ "mount point", "UUID");
+ for (len=get_terminal_width()-1; len > 0; len--)
+ fputc('-', stdout);
+ fputc('\n', stdout);
+ return;
+ }
+
+ devname = blkid_dev_devname(dev);
+ if (access(devname, F_OK))
+ return;
+
+ /* Get the uuid, label, type */
+ iter = blkid_tag_iterate_begin(dev);
+ while (blkid_tag_next(iter, &type, &value) == 0) {
+ if (!strcmp(type, "UUID"))
+ uuid = value;
+ if (!strcmp(type, "TYPE"))
+ fs_type = value;
+ if (!strcmp(type, "LABEL"))
+ label = value;
+ }
+ blkid_tag_iterate_end(iter);
+
+ /* Get the mount point */
+ mtpt[0] = 0;
+ retval = ext2fs_check_mount_point(devname, &mount_flags,
+ mtpt, sizeof(mtpt));
+ if (retval == 0) {
+ if (mount_flags & EXT2_MF_MOUNTED) {
+ if (!mtpt[0])
+ strcpy(mtpt, "(mounted, mtpt unknown)");
+ } else if (mount_flags & EXT2_MF_BUSY)
+ strcpy(mtpt, "(in use)");
+ else
+ strcpy(mtpt, "(not mounted)");
+ }
+
+ pretty_print_line(devname, fs_type, label, mtpt, uuid);
+#endif
+}
+
+static void print_udev_format(const char *name, const char *value, size_t sz)
+{
+ char enc[265], safe[256];
+
+ *safe = *enc = '\0';
+
+ if (!strcmp(name, "TYPE") || !strcmp(name, "VERSION")) {
+ blkid_encode_string(value, enc, sizeof(enc));
+ printf("ID_FS_%s=%s\n", name, enc);
+
+ } else if (!strcmp(name, "UUID") ||
+ !strcmp(name, "LABEL") ||
+ !strcmp(name, "UUID_SUB")) {
+
+ blkid_safe_string(value, safe, sizeof(safe));
+ printf("ID_FS_%s=%s\n", name, safe);
+
+ blkid_encode_string(value, enc, sizeof(enc));
+ printf("ID_FS_%s_ENC=%s\n", name, enc);
+ }
+ else
+ printf("ID_FS_%s=%s\n", name, value);
+}
+
+static void print_value(int output, int num, const char *devname,
+ const char *value, const char *name, size_t valsz)
+{
+ if (output & OUTPUT_VALUE_ONLY) {
+ fputs(value, stdout);
+ fputc('\n', stdout);
+
+ } else if (output & OUTPUT_UDEV_LIST) {
+ print_udev_format(name, value, valsz);
+
+ } else {
+ if (num == 1 && devname)
+ printf("%s: ", devname);
+ fputs(name, stdout);
+ fputs("=\"", stdout);
+ safe_print(value, valsz);
+ fputs("\" ", stdout);
+ }
+}
+
+static void print_tags(blkid_dev dev, char *show[], int numtag, int output)
+{
+ blkid_tag_iterate iter;
+ const char *type, *value, *devname;
+ int i, num = 1;
+
+ if (!dev)
+ return;
+
+ if (output & OUTPUT_PRETTY_LIST) {
+ pretty_print_dev(dev);
+ return;
+ }
+
+ devname = blkid_dev_devname(dev);
+
+ if (output & OUTPUT_DEVICE_ONLY) {
+ printf("%s\n", devname);
+ return;
+ }
+
+ iter = blkid_tag_iterate_begin(dev);
+ while (blkid_tag_next(iter, &type, &value) == 0) {
+ if (numtag && show) {
+ for (i=0; i < numtag; i++)
+ if (!strcmp(type, show[i]))
+ break;
+ if (i >= numtag)
+ continue;
+ }
+ print_value(output, num++, devname, value, type, strlen(value));
+ }
+ blkid_tag_iterate_end(iter);
+
+ if (num > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
+ printf("\n");
+}
+
+static int lowprobe_device(blkid_probe pr, const char *devname, int output,
+ blkid_loff_t offset, blkid_loff_t size)
+{
+ const char *data;
+ const char *name;
+ int nvals = 0, n;
+ size_t len;
+ int fd;
+ int rc = 0;
+
+ fd = open(devname, O_RDONLY);
+ if (fd < 0)
+ return 2;
+
+ if (blkid_probe_set_device(pr, fd, offset, size))
+ goto done;
+ rc = blkid_do_safeprobe(pr);
+ if (rc)
+ goto done;
+
+ nvals = blkid_probe_numof_values(pr);
+
+ if (output & OUTPUT_DEVICE_ONLY) {
+ printf("%s\n", devname);
+ goto done;
+ }
+
+ for (n = 0; n < nvals; n++) {
+ if (blkid_probe_get_value(pr, n, &name, &data, &len))
+ continue;
+
+ len = strnlen((char *) data, len);
+ print_value(output, n + 1, devname, (char *) data, name, len);
+ }
+
+ if (nvals > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST)))
+ printf("\n");
+done:
+ if (rc == -2)
+ fprintf(stderr, "%s: ambivalent result "
+ "(probably more filesystems on the device)\n",
+ devname);
+ close(fd);
+ return !nvals ? 2 : 0;
+}
+
+/* converts comma separated list to BLKID_USAGE_* mask */
+static int list_to_usage(const char *list, int *flag)
+{
+ int mask = 0;
+ const char *word, *p = list;
+
+ if (p && strncmp(p, "no", 2) == 0) {
+ *flag = BLKID_FLTR_NOTIN;
+ p += 2;
+ }
+
+ for (word = p; p && *p; p++) {
+ if (*p == ',' || *(p + 1) == '\0') {
+ if (!strncmp(word, "filesystem", 10))
+ mask |= BLKID_USAGE_FILESYSTEM;
+ else if (!strncmp(word, "raid", 4))
+ mask |= BLKID_USAGE_RAID;
+ else if (!strncmp(word, "crypto", 6))
+ mask |= BLKID_USAGE_CRYPTO;
+ else if (!strncmp(word, "other", 5))
+ mask |= BLKID_USAGE_OTHER;
+ else {
+ fprintf(stderr, "unknown usage keyword '%*s'\n",
+ (int) (p - word), word);
+ exit(4);
+ }
+ word = p + 1;
+ }
+ }
+ return mask;
+}
+
+int main(int argc, char **argv)
+{
+ blkid_cache cache = NULL;
+ char *devices[128] = { NULL, };
+ char *show[128] = { NULL, };
+ char *search_type = NULL, *search_value = NULL;
+ char *read = NULL;
+ char *write = NULL;
+ int fltr_usage = 0;
+ int fltr_flag = BLKID_FLTR_ONLYIN;
+ unsigned int numdev = 0, numtag = 0;
+ int version = 0;
+ int err = 4;
+ unsigned int i;
+ int output_format = 0;
+ int lookup = 0, gc = 0, lowprobe = 0, eval = 0;
+ int c;
+ blkid_loff_t offset = 0, size = 0;
+
+ while ((c = getopt (argc, argv, "c:f:ghlL:o:O:ps:S:t:u:U:w:v")) != EOF)
+ switch (c) {
+ case 'c':
+ if (optarg && !*optarg)
+ read = NULL;
+ else
+ read = optarg;
+ if (!write)
+ write = read;
+ break;
+ case 'L':
+ eval++;
+ search_value = strdup(optarg);
+ search_type = strdup("LABEL");
+ break;
+ case 'u':
+ fltr_usage = list_to_usage(optarg, &fltr_flag);
+ break;
+ case 'U':
+ eval++;
+ search_value = strdup(optarg);
+ search_type = strdup("UUID");
+ break;
+ case 'l':
+ lookup++;
+ break;
+ case 'g':
+ gc = 1;
+ break;
+ case 'o':
+ if (!strcmp(optarg, "value"))
+ output_format = OUTPUT_VALUE_ONLY;
+ else if (!strcmp(optarg, "device"))
+ output_format = OUTPUT_DEVICE_ONLY;
+ else if (!strcmp(optarg, "list"))
+ output_format = OUTPUT_PRETTY_LIST;
+ else if (!strcmp(optarg, "udev"))
+ output_format = OUTPUT_UDEV_LIST;
+ else if (!strcmp(optarg, "full"))
+ output_format = 0;
+ else {
+ fprintf(stderr, "Invalid output format %s. "
+ "Choose from value,\n\t"
+ "device, list, udev or full\n", optarg);
+ exit(4);
+ }
+ break;
+ case 'O':
+ offset = strtoll(optarg, NULL, 10);
+ break;
+ case 'p':
+ lowprobe++;
+ break;
+ case 's':
+ if (numtag >= sizeof(show) / sizeof(*show)) {
+ fprintf(stderr, "Too many tags specified\n");
+ usage(err);
+ }
+ show[numtag++] = optarg;
+ break;
+ case 'S':
+ size = strtoll(optarg, NULL, 10);
+ break;
+ case 't':
+ if (search_type) {
+ fprintf(stderr, "Can only search for "
+ "one NAME=value pair\n");
+ usage(err);
+ }
+ if (blkid_parse_tag_string(optarg,
+ &search_type,
+ &search_value)) {
+ fprintf(stderr, "-t needs NAME=value pair\n");
+ usage(err);
+ }
+ break;
+ case 'v':
+ version = 1;
+ break;
+ case 'w':
+ if (optarg && !*optarg)
+ write = NULL;
+ else
+ write = optarg;
+ break;
+ case 'h':
+ err = 0;
+ default:
+ usage(err);
+ }
+
+ while (optind < argc)
+ devices[numdev++] = argv[optind++];
+
+ if (version) {
+ print_version(stdout);
+ goto exit;
+ }
+
+ /* convert LABEL/UUID lookup to evaluate request */
+ if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type &&
+ (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) {
+ eval++;
+ lookup = 0;
+ }
+
+ if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0)
+ goto exit;
+
+ if (gc) {
+ blkid_gc_cache(cache);
+ err = 0;
+ goto exit;
+ }
+ err = 2;
+
+ if (output_format & OUTPUT_PRETTY_LIST)
+ pretty_print_dev(NULL);
+
+ if (lowprobe) {
+ /*
+ * Low-level API
+ */
+ blkid_probe pr;
+
+ if (!numdev) {
+ fprintf(stderr, "The low-probe option requires a device\n");
+ exit(4);
+ }
+ pr = blkid_new_probe();
+ if (!pr)
+ goto exit;
+ blkid_probe_set_request(pr,
+ BLKID_PROBREQ_LABEL | BLKID_PROBREQ_UUID |
+ BLKID_PROBREQ_TYPE | BLKID_PROBREQ_SECTYPE |
+ BLKID_PROBREQ_USAGE | BLKID_PROBREQ_VERSION);
+ if (fltr_usage &&
+ blkid_probe_filter_usage(pr, fltr_flag, fltr_usage))
+ goto exit;
+
+ for (i = 0; i < numdev; i++)
+ err = lowprobe_device(pr, devices[i],
+ output_format, offset, size);
+ blkid_free_probe(pr);
+ } else if (eval) {
+ /*
+ * Evaluate API
+ */
+ char *res = blkid_evaluate_tag(search_type, search_value, NULL);
+ if (res) {
+ err = 0;
+ printf("%s\n", res);
+ }
+ } else if (lookup) {
+ /*
+ * Classic (cache based) API
+ */
+ blkid_dev dev;
+
+ if (!search_type) {
+ fprintf(stderr, "The lookup option requires a "
+ "search type specified using -t\n");
+ exit(4);
+ }
+ /* Load any additional devices not in the cache */
+ for (i = 0; i < numdev; i++)
+ blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL);
+
+ if ((dev = blkid_find_dev_with_tag(cache, search_type,
+ search_value))) {
+ print_tags(dev, show, numtag, output_format);
+ err = 0;
+ }
+ /* If we didn't specify a single device, show all available devices */
+ } else if (!numdev) {
+ blkid_dev_iterate iter;
+ blkid_dev dev;
+
+ blkid_probe_all(cache);
+
+ iter = blkid_dev_iterate_begin(cache);
+ blkid_dev_set_search(iter, search_type, search_value);
+ while (blkid_dev_next(iter, &dev) == 0) {
+ dev = blkid_verify(cache, dev);
+ if (!dev)
+ continue;
+ print_tags(dev, show, numtag, output_format);
+ err = 0;
+ }
+ blkid_dev_iterate_end(iter);
+ /* Add all specified devices to cache (optionally display tags) */
+ } else for (i = 0; i < numdev; i++) {
+ blkid_dev dev = blkid_get_dev(cache, devices[i],
+ BLKID_DEV_NORMAL);
+
+ if (dev) {
+ if (search_type &&
+ !blkid_dev_has_tag(dev, search_type,
+ search_value))
+ continue;
+ print_tags(dev, show, numtag, output_format);
+ err = 0;
+ }
+ }
+
+exit:
+ free(search_type);
+ free(search_value);
+ if (!lowprobe && !eval)
+ blkid_put_cache(cache);
+ return err;
+}
diff --git a/shlibs/blkid/bin/blkid.sh.in b/shlibs/blkid/bin/blkid.sh.in
new file mode 100644
index 000000000..3e10add11
--- /dev/null
+++ b/shlibs/blkid/bin/blkid.sh.in
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# libtool? Don't ask!
+
+BLKIDDIR=@SRCDIR@/libs/blkid
+BINARY=$BLKIDDIR/bin/blkid
+LD_LIBRARY_PATH=$BLKIDDIR/src/
+
+export LD_LIBRARY_PATH
+exec $BINARY $@
diff --git a/shlibs/blkid/bin/findfs.8 b/shlibs/blkid/bin/findfs.8
new file mode 100644
index 000000000..e93fe5421
--- /dev/null
+++ b/shlibs/blkid/bin/findfs.8
@@ -0,0 +1,35 @@
+.\" -*- nroff -*-
+.\" Copyright 1993, 1994, 1995 by Theodore Ts'o. All Rights Reserved.
+.\" This file may be copied under the terms of the GNU Public License.
+.\"
+.TH FINDFS 8 "February 2009" "Linux" "MAINTENANCE COMMANDS"
+.SH NAME
+findfs \- Find a filesystem by label or UUID
+.SH SYNOPSIS
+.B findfs
+.BI LABEL= label
+.sp
+.B findfs
+.BI UUID= uuid
+.SH DESCRIPTION
+.B findfs
+will search the disks in the system looking for a filesystem which has
+a label matching
+.I label
+or a UUID equal to
+.IR uuid .
+If the filesystem is found, the device name for the filesystem will
+be printed on stdout.
+.PP
+.SH AUTHOR
+.B findfs
+was originally written by Theodore Ts'o (tytso@mit.edu) and re-written for
+util-linux-ng package by Karel Zak (kzak@redhat.com).
+.SH AVAILABILITY
+.B findfs
+The blkid command is part of the util-linux-ng package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+.SH SEE ALSO
+.BR blkid (8)
+.BR fsck (8)
+
diff --git a/shlibs/blkid/bin/findfs.c b/shlibs/blkid/bin/findfs.c
new file mode 100644
index 000000000..18608b470
--- /dev/null
+++ b/shlibs/blkid/bin/findfs.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+
+#include <blkid.h>
+
+#include "nls.h"
+
+static void __attribute__((__noreturn__)) usage(int rc)
+{
+ const char *p = program_invocation_short_name;
+
+ if (!p)
+ p = "findfs";
+
+ fprintf(stderr, _("Usage: %s LABEL=<label>|UUID=<uuid>\n"), p);
+ exit(rc);
+}
+
+int main(int argc, char **argv)
+{
+ char *dev, *tk, *vl;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ if (argc != 2)
+ /* we return '2' for backward compatibility
+ * with version from e2fsprogs */
+ usage(2);
+
+ if (!strncmp(argv[1], "LABEL=", 6)) {
+ tk = "LABEL";
+ vl = argv[1] + 6;
+ } else if (!strncmp(argv[1], "UUID=", 5)) {
+ tk = "UUID";
+ vl = argv[1] + 5;
+ } else if (!strcmp(argv[1], "-h") == 0 ||
+ !strcmp(argv[1], "--help") == 0) {
+ usage(EXIT_SUCCESS);
+ } else
+ usage(2);
+
+ dev = blkid_evaluate_tag(tk, vl, NULL);
+ if (!dev)
+ errx(EXIT_FAILURE, _("unable to resolve '%s'"), argv[1]);
+
+ puts(dev);
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/shlibs/blkid/bin/findfs.sh.in b/shlibs/blkid/bin/findfs.sh.in
new file mode 100644
index 000000000..37876c76e
--- /dev/null
+++ b/shlibs/blkid/bin/findfs.sh.in
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# libtool? Don't ask!
+
+BLKIDDIR=@SRCDIR@/libs/blkid
+BINARY=$BLKIDDIR/bin/findfs
+LD_LIBRARY_PATH=$BLKIDDIR/src/
+
+export LD_LIBRARY_PATH
+exec $BINARY $@
diff --git a/shlibs/blkid/blkid.pc.in b/shlibs/blkid/blkid.pc.in
new file mode 100644
index 000000000..5d58c3e19
--- /dev/null
+++ b/shlibs/blkid/blkid.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: blkid
+Description: Block device id library
+Version: @LIBBLKID_VERSION@
+Requires.private: uuid
+Cflags: -I${includedir}/blkid
+Libs: -L${libdir} -lblkid
diff --git a/shlibs/blkid/libblkid.3 b/shlibs/blkid/libblkid.3
new file mode 100644
index 000000000..89747ecf1
--- /dev/null
+++ b/shlibs/blkid/libblkid.3
@@ -0,0 +1,81 @@
+.\" Copyright 2001 Andreas Dilger (adilger@turbolinux.com)
+.\"
+.\" This man page was created for libblkid.so.1.0 from e2fsprogs-1.24.
+.\"
+.\" This file may be copied under the terms of the GNU Public License.
+.\"
+.\" Created Wed Sep 14 12:02:12 2001, Andreas Dilger
+.TH LIBBLKID 3 "February 2009" "Linux" "MAINTENANCE COMMANDS""
+.SH NAME
+libblkid \- block device identification library
+.SH SYNOPSIS
+.B #include <blkid/blkid.h>
+.sp
+.B cc
+.I file.c
+.B \-lblkid
+.SH DESCRIPTION
+The
+.B libblkid
+library is used to identify block devices (disks) as to their content (e.g.
+filesystem type) as well as extracting additional information such as
+filesystem labels/volume names, unique identifiers/serial numbers, etc.
+A common use is to allow use of LABEL= and UUID= tags instead of hard-coding
+specific block device names into configuration files.
+.P
+Block device information is normally kept in a cache file
+.I /etc/blkid.tab
+and is verified to still be valid before being returned to the user
+(if the user has read permission on the raw block device, otherwise not).
+The cache file also allows unprivileged users (normally anyone other
+than root, or those not in the "disk" group) to locate devices by label/id.
+The standard location of the cache file can be overridden by the
+environment variable BLKID_FILE.
+.P
+In situations where one is getting information about a single known device,
+it does not impact performance whether the cache is used or not (unless you
+are not able to read the block device directly). If you are dealing with
+multiple devices, use of the cache is highly recommended (even if empty) as
+devices will be scanned at most one time and the on-disk cache will be
+updated if possible. There is rarely a reason not to use the cache.
+.P
+In some cases (modular kernels), block devices are not even visible until
+after they are accessed the first time, so it is critical that there is
+some way to locate these devices without enumerating only visible devices,
+so the use of the cache file is
+.B required
+in this situation.
+.SH AUTHOR
+.B libblkid
+was written by Andreas Dilger for the ext2 filesystem utilties, with input
+from Ted Ts'o. The library was subsequently heavily modified by Ted Ts'o.
+.SH FILES
+.TP
+.I /etc/blkid.tab
+Caches data extracted from each recognized block device.
+.SH AVAILABILITY
+.B libblkid
+is part of the util-linux-ng package since version 2.15 and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+.SH COPYING
+.B libblkid
+is available under the terms of the GNU Library General Public License (LGPL),
+version 2 (or at your discretion any later version). A copy of the LGPL
+should be included with this library in the file COPYING. If not, write to
+.RS
+Free Software Foundation, Inc.
+.br
+51 Franklin St
+.br
+Fifth Floor
+.br
+Boston, MA 02110-1301 USA
+.RE
+.PP
+or visit
+.UR http://www.gnu.org/licenses/licenses.html#LGPL
+http://www.gnu.org/licenses/licenses.html#LGPL
+.UE
+.SH "SEE ALSO"
+.BR blkid (8)
+.BR findfs (8)
diff --git a/shlibs/blkid/src/Makefile.am b/shlibs/blkid/src/Makefile.am
new file mode 100644
index 000000000..805d0899b
--- /dev/null
+++ b/shlibs/blkid/src/Makefile.am
@@ -0,0 +1,45 @@
+include $(top_srcdir)/config/include-Makefile.am
+
+SUBDIRS = probers .
+
+AM_CPPFLAGS += -I$(top_srcdir)/libs/blkid/src
+
+common_ldadd =
+
+if HAVE_UUID
+common_ldadd += -luuid #TODO $(UUID_LIBS)
+endif
+
+# includes
+blkidincdir = $(includedir)/blkid
+blkidinc_HEADERS = blkid.h
+
+lib_LTLIBRARIES = libblkid.la
+libblkid_la_SOURCES = cache.c dev.c devname.c devno.c getsize.c llseek.c \
+ probe.c read.c resolve.c save.c tag.c version.c verify.c \
+ encode.c blkid.h list.h blkidP.h probers/probers.h \
+ config.c evaluate.c \
+ $(blkidinc_HEADERS) \
+ $(top_srcdir)/lib/blkdev.c \
+ $(top_srcdir)/lib/linux_version.c \
+ $(top_srcdir)/lib/canonicalize.c \
+ $(top_srcdir)/lib/md5.c
+
+libblkid_la_LIBADD = probers/libblkid_probers.la $(common_ldadd)
+libblkid_la_DEPENDENCIES = $(libblkid_la_LIBADD) blkid.sym
+
+# TODO: for unknown reason "make distcheck" requires
+# full path to the version script
+libblkid_la_LDFLAGS = -Wl,--version-script=$(top_srcdir)/libs/blkid/src/blkid.sym \
+ -version-info 1:0:0
+
+tests = test_cache test_config test_dev test_devname test_devno test_getsize \
+ test_read test_resolve test_save test_tag test_verify test_evaluate
+
+EXTRA_DIST = blkid.sym tst_types.c
+CLEANFILES = $(tests)
+
+tests: all $(tests)
+test_%: %.c
+ $(COMPILE) -DTEST_PROGRAM $< .libs/libblkid.a -o $@ $(common_ldadd)
+
diff --git a/shlibs/blkid/src/blkid.h b/shlibs/blkid/src/blkid.h
new file mode 100644
index 000000000..43b2b5529
--- /dev/null
+++ b/shlibs/blkid/src/blkid.h
@@ -0,0 +1,171 @@
+/*
+ * blkid.h - Interface for libblkid, a library to identify block devices
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _BLKID_BLKID_H
+#define _BLKID_BLKID_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct blkid_struct_dev *blkid_dev;
+typedef struct blkid_struct_cache *blkid_cache;
+typedef struct blkid_struct_probe *blkid_probe;
+
+typedef int64_t blkid_loff_t;
+
+typedef struct blkid_struct_tag_iterate *blkid_tag_iterate;
+typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
+
+/*
+ * Flags for blkid_get_dev
+ *
+ * BLKID_DEV_CREATE Create an empty device structure if not found
+ * in the cache.
+ * BLKID_DEV_VERIFY Make sure the device structure corresponds
+ * with reality.
+ * BLKID_DEV_FIND Just look up a device entry, and return NULL
+ * if it is not found.
+ * BLKID_DEV_NORMAL Get a valid device structure, either from the
+ * cache or by probing the device.
+ */
+#define BLKID_DEV_FIND 0x0000
+#define BLKID_DEV_CREATE 0x0001
+#define BLKID_DEV_VERIFY 0x0002
+#define BLKID_DEV_NORMAL (BLKID_DEV_CREATE | BLKID_DEV_VERIFY)
+
+/* cache.c */
+extern void blkid_put_cache(blkid_cache cache);
+extern int blkid_get_cache(blkid_cache *cache, const char *filename);
+extern void blkid_gc_cache(blkid_cache cache);
+
+/* dev.c */
+extern const char *blkid_dev_devname(blkid_dev dev);
+
+extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache);
+extern int blkid_dev_set_search(blkid_dev_iterate iter,
+ char *search_type, char *search_value);
+extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev);
+extern void blkid_dev_iterate_end(blkid_dev_iterate iterate);
+
+/* devno.c */
+extern char *blkid_devno_to_devname(dev_t devno);
+
+/* devname.c */
+extern int blkid_probe_all(blkid_cache cache);
+extern int blkid_probe_all_new(blkid_cache cache);
+extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname,
+ int flags);
+
+/* getsize.c */
+extern blkid_loff_t blkid_get_dev_size(int fd);
+
+/* verify.c */
+extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev);
+
+/* read.c */
+
+/* resolve.c */
+extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
+ const char *devname);
+extern char *blkid_get_devname(blkid_cache cache, const char *token,
+ const char *value);
+
+/* tag.c */
+extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev);
+extern int blkid_tag_next(blkid_tag_iterate iterate,
+ const char **type, const char **value);
+extern void blkid_tag_iterate_end(blkid_tag_iterate iterate);
+extern int blkid_dev_has_tag(blkid_dev dev, const char *type,
+ const char *value);
+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
+ const char *type,
+ const char *value);
+extern int blkid_parse_tag_string(const char *token, char **ret_type,
+ char **ret_val);
+
+/* version.c */
+extern int blkid_parse_version_string(const char *ver_string);
+extern int blkid_get_library_version(const char **ver_string,
+ const char **date_string);
+
+/* encode.c */
+extern int blkid_encode_string(const char *str, char *str_enc, size_t len);
+extern int blkid_safe_string(const char *str, char *str_safe, size_t len);
+
+/* evaluate.c */
+extern int blkid_send_uevent(const char *devname, const char *action);
+extern char *blkid_evaluate_tag(const char *token, const char *value,
+ blkid_cache *cache);
+
+/* probe.c */
+extern int blkid_known_fstype(const char *fstype);
+extern blkid_probe blkid_new_probe(void);
+extern void blkid_free_probe(blkid_probe pr);
+extern void blkid_reset_probe(blkid_probe pr);
+
+extern int blkid_probe_set_device(blkid_probe pr, int fd,
+ blkid_loff_t off, blkid_loff_t size);
+
+#define BLKID_PROBREQ_LABEL (1 << 1)
+#define BLKID_PROBREQ_LABELRAW (1 << 2)
+#define BLKID_PROBREQ_UUID (1 << 3)
+#define BLKID_PROBREQ_UUIDRAW (1 << 4)
+#define BLKID_PROBREQ_TYPE (1 << 5)
+#define BLKID_PROBREQ_SECTYPE (1 << 6)
+#define BLKID_PROBREQ_USAGE (1 << 7)
+#define BLKID_PROBREQ_VERSION (1 << 8)
+extern int blkid_probe_set_request(blkid_probe pr, int flags);
+
+#define BLKID_USAGE_FILESYSTEM (1 << 1)
+#define BLKID_USAGE_RAID (1 << 2)
+#define BLKID_USAGE_CRYPTO (1 << 3)
+#define BLKID_USAGE_OTHER (1 << 4)
+extern int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage);
+
+#define BLKID_FLTR_NOTIN 1
+#define BLKID_FLTR_ONLYIN 2
+extern int blkid_probe_filter_types(blkid_probe pr,
+ int flag, char *names[]);
+
+
+extern int blkid_probe_invert_filter(blkid_probe pr);
+extern int blkid_probe_reset_filter(blkid_probe pr);
+
+extern int blkid_do_probe(blkid_probe pr);
+extern int blkid_do_safeprobe(blkid_probe pr);
+
+extern int blkid_probe_numof_values(blkid_probe pr);
+extern int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
+ const char **data, size_t *len);
+extern int blkid_probe_lookup_value(blkid_probe pr, const char *name,
+ const char **data, size_t *len);
+extern int blkid_probe_has_value(blkid_probe pr, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLKID_BLKID_H */
diff --git a/shlibs/blkid/src/blkid.sym b/shlibs/blkid/src/blkid.sym
new file mode 100644
index 000000000..562f44d0c
--- /dev/null
+++ b/shlibs/blkid/src/blkid.sym
@@ -0,0 +1,68 @@
+/*
+ * The symbol versioning ensures that a new application requiring symbol foo()
+ * can't run with old libblkid.so not providing foo() - the global SONAME
+ * version info can't enforce this since we never change the SONAME.
+ *
+ * The original libblkid from e2fsprogs (<=1.41.4) does not to use
+ * symbol versioning -- all the original symbols are in BLKID_1.0 now.
+ */
+BLKID_1.0 {
+global:
+ blkid_dev_devname;
+ blkid_dev_has_tag;
+ blkid_dev_iterate_begin;
+ blkid_dev_iterate_end;
+ blkid_dev_next;
+ blkid_devno_to_devname;
+ blkid_dev_set_search;
+ blkid_find_dev_with_tag;
+ blkid_gc_cache;
+ blkid_get_cache;
+ blkid_get_dev;
+ blkid_get_devname;
+ blkid_get_dev_size;
+ blkid_get_library_version;
+ blkid_get_tag_value;
+ blkid_known_fstype;
+ blkid_parse_tag_string;
+ blkid_parse_version_string;
+ blkid_probe_all;
+ blkid_probe_all_new;
+ blkid_put_cache;
+ blkid_tag_iterate_begin;
+ blkid_tag_iterate_end;
+ blkid_tag_next;
+ blkid_verify;
+local:
+ *;
+};
+
+
+/*
+ * version(s) since util-linux-ng 2.15
+ */
+BLKID_2.15 {
+global:
+ blkid_do_probe;
+ blkid_do_safeprobe;
+ blkid_encode_string;
+ blkid_evaluate_tag;
+ blkid_free_probe;
+ blkid_new_probe;
+ blkid_probe_all;
+ blkid_probe_all_new;
+ blkid_probe_filter_types;
+ blkid_probe_filter_usage;
+ blkid_probe_get_value;
+ blkid_probe_has_value;
+ blkid_probe_invert_filter;
+ blkid_probe_lookup_value;
+ blkid_probe_numof_values;
+ blkid_probe_reset_filter;
+ blkid_probe_set_device;
+ blkid_probe_set_request;
+ blkid_reset_probe;
+ blkid_safe_string;
+ blkid_send_uevent;
+} BLKID_1.0;
+
diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h
new file mode 100644
index 000000000..4131c5bba
--- /dev/null
+++ b/shlibs/blkid/src/blkidP.h
@@ -0,0 +1,343 @@
+/*
+ * blkidP.h - Internal interfaces for libblkid
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#ifndef _BLKID_BLKIDP_H
+#define _BLKID_BLKIDP_H
+
+
+#define CONFIG_BLKID_DEBUG 1
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#include "bitops.h" /* $(top_srcdir)/include/ */
+#include "blkid.h"
+#include "list.h"
+
+#ifdef __GNUC__
+#define __BLKID_ATTR(x) __attribute__(x)
+#else
+#define __BLKID_ATTR(x)
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 1
+#endif
+
+#include <limits.h>
+#ifndef PATH_MAX
+# define PATH_MAX 4096
+#endif
+
+/* TODO: move to some top-level util-linux include file */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+/*
+ * This describes the attributes of a specific device.
+ * We can traverse all of the tags by bid_tags (linking to the tag bit_names).
+ * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag
+ * values, if they exist.
+ */
+struct blkid_struct_dev
+{
+ struct list_head bid_devs; /* All devices in the cache */
+ struct list_head bid_tags; /* All tags for this device */
+ blkid_cache bid_cache; /* Dev belongs to this cache */
+ char *bid_name; /* Device inode pathname */
+ char *bid_type; /* Preferred device TYPE */
+ int bid_pri; /* Device priority */
+ dev_t bid_devno; /* Device major/minor number */
+ time_t bid_time; /* Last update time of device */
+ unsigned int bid_flags; /* Device status bitflags */
+ char *bid_label; /* Shortcut to device LABEL */
+ char *bid_uuid; /* Shortcut to binary UUID */
+};
+
+#define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */
+#define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */
+
+/*
+ * Each tag defines a NAME=value pair for a particular device. The tags
+ * are linked via bit_names for a single device, so that traversing the
+ * names list will get you a list of all tags associated with a device.
+ * They are also linked via bit_values for all devices, so one can easily
+ * search all tags with a given NAME for a specific value.
+ */
+struct blkid_struct_tag
+{
+ struct list_head bit_tags; /* All tags for this device */
+ struct list_head bit_names; /* All tags with given NAME */
+ char *bit_name; /* NAME of tag (shared) */
+ char *bit_val; /* value of tag */
+ blkid_dev bit_dev; /* pointer to device */
+};
+typedef struct blkid_struct_tag *blkid_tag;
+
+/*
+ * Low-level probe result
+ */
+#define BLKID_PROBVAL_BUFSIZ 64
+#define BLKID_PROBVAL_NVALS 8 /* see blkid.h BLKID_PROBREQ_* */
+
+struct blkid_prval
+{
+ const char *name; /* value name */
+ unsigned char data[BLKID_PROBVAL_BUFSIZ]; /* value data */
+ size_t len; /* length of value data */
+};
+
+/*
+ * Low-level probing control struct
+ */
+struct blkid_struct_probe
+{
+ int fd; /* device file descriptor */
+ blkid_loff_t off; /* begin of data on the device */
+ blkid_loff_t size; /* end of data on the device */
+
+ unsigned char *sbbuf; /* superblok buffer */
+ size_t sbbuf_len; /* size of data in superblock buffer */
+
+ unsigned char *buf; /* seek buffer */
+ blkid_loff_t buf_off; /* offset of seek buffer */
+ size_t buf_len; /* size of data in seek buffer */
+ size_t buf_max; /* allocated size of seek buffer */
+
+ struct blkid_prval vals[BLKID_PROBVAL_NVALS];
+ int nvals;
+
+ int probreq; /* BLKID_PROBREQ_* flags */
+ int idx; /* index of the last prober */
+
+ unsigned long *fltr; /* filter */
+};
+
+#define BLKID_SB_BUFSIZ 0x11000
+
+/*
+ * Filesystem / Raid magic strings
+ */
+struct blkid_idmag
+{
+ const char *magic; /* magic string */
+ unsigned len; /* length of magic */
+
+ long kboff; /* kilobyte offset of superblock */
+ unsigned sboff; /* byte offset within superblock */
+};
+
+/*
+ * Filesystem / Raid description
+ */
+struct blkid_idinfo
+{
+ const char *name; /* FS/RAID name */
+ int usage; /* BLKID_USAGE_* flag */
+ int flags; /* BLKID_IDINFO_* flags */
+
+ /* probe function */
+ int (*probefunc)(blkid_probe pr, const struct blkid_idmag *mag);
+
+ struct blkid_idmag magics[]; /* NULL or array with magic strings */
+};
+
+#define BLKID_NONE_MAGIC {{ NULL }}
+
+/*
+ * tolerant FS - can share the same device with more filesystems (e.g. typical
+ * on CD-ROMs). We need this flag to detect ambivalent results (e.g. valid fat
+ * and valid linux swap on the same device).
+ */
+#define BLKID_IDINFO_TOLERANT (1 << 1)
+
+/*
+ * Evaluation methods (for blkid_eval_* API)
+ */
+enum {
+ BLKID_EVAL_UDEV = 0,
+ BLKID_EVAL_SCAN,
+
+ __BLKID_EVAL_LAST
+};
+
+/*
+ * Library config options
+ */
+struct blkid_config {
+ int eval[__BLKID_EVAL_LAST]; /* array with EVALUATION=<udev,cache> options */
+ int nevals; /* number of elems in eval array */
+ int uevent; /* SEND_UEVENT=<yes|not> option */
+ char *cachefile; /* CACHE_FILE=<path> option */
+};
+
+extern struct blkid_config *blkid_read_config(const char *filename);
+extern void blkid_free_config(struct blkid_config *conf);
+
+/*
+ * Minimum number of seconds between device probes, even when reading
+ * from the cache. This is to avoid re-probing all devices which were
+ * just probed by another program that does not share the cache.
+ */
+#define BLKID_PROBE_MIN 2
+
+/*
+ * Time in seconds an entry remains verified in the in-memory cache
+ * before being reverified (in case of long-running processes that
+ * keep a cache in memory and continue to use it for a long time).
+ */
+#define BLKID_PROBE_INTERVAL 200
+
+/* This describes an entire blkid cache file and probed devices.
+ * We can traverse all of the found devices via bic_list.
+ * We can traverse all of the tag types by bic_tags, which hold empty tags
+ * for each tag type. Those tags can be used as list_heads for iterating
+ * through all devices with a specific tag type (e.g. LABEL).
+ */
+struct blkid_struct_cache
+{
+ struct list_head bic_devs; /* List head of all devices */
+ struct list_head bic_tags; /* List head of all tag types */
+ time_t bic_time; /* Last probe time */
+ time_t bic_ftime; /* Mod time of the cachefile */
+ unsigned int bic_flags; /* Status flags of the cache */
+ char *bic_filename; /* filename of cache */
+ blkid_probe probe; /* low-level probing stuff */
+};
+
+#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */
+#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */
+
+extern char *blkid_strdup(const char *s);
+extern char *blkid_strndup(const char *s, const int length);
+
+#define BLKID_CACHE_FILE "/etc/blkid.tab"
+#define BLKID_CONFIG_FILE "/etc/blkid.conf"
+
+#define BLKID_ERR_IO 5
+#define BLKID_ERR_PROC 9
+#define BLKID_ERR_MEM 12
+#define BLKID_ERR_CACHE 14
+#define BLKID_ERR_DEV 19
+#define BLKID_ERR_PARAM 22
+#define BLKID_ERR_BIG 27
+
+/*
+ * Priority settings for different types of devices
+ */
+#define BLKID_PRI_DM 40
+#define BLKID_PRI_EVMS 30
+#define BLKID_PRI_LVM 20
+#define BLKID_PRI_MD 10
+
+#if defined(TEST_PROGRAM) && !defined(CONFIG_BLKID_DEBUG)
+#define CONFIG_BLKID_DEBUG
+#endif
+
+#define DEBUG_CACHE 0x0001
+#define DEBUG_DUMP 0x0002
+#define DEBUG_DEV 0x0004
+#define DEBUG_DEVNAME 0x0008
+#define DEBUG_DEVNO 0x0010
+#define DEBUG_PROBE 0x0020
+#define DEBUG_READ 0x0040
+#define DEBUG_RESOLVE 0x0080
+#define DEBUG_SAVE 0x0100
+#define DEBUG_TAG 0x0200
+#define DEBUG_LOWPROBE 0x0400
+#define DEBUG_CONFIG 0x0800
+#define DEBUG_EVALUATE 0x1000
+#define DEBUG_INIT 0x8000
+#define DEBUG_ALL 0xFFFF
+
+#ifdef CONFIG_BLKID_DEBUG
+#include <stdio.h>
+extern int blkid_debug_mask;
+extern void blkid_init_debug(int mask);
+extern void blkid_debug_dump_dev(blkid_dev dev);
+extern void blkid_debug_dump_tag(blkid_tag tag);
+
+#define DBG(m,x) if ((m) & blkid_debug_mask) x;
+
+#else /* !CONFIG_BLKID_DEBUG */
+#define DBG(m,x)
+#define blkid_init_debug(x)
+#endif /* CONFIG_BLKID_DEBUG */
+
+/* devno.c */
+struct dir_list {
+ char *name;
+ struct dir_list *next;
+};
+extern void blkid__scan_dir(char *, dev_t, struct dir_list **, char **);
+
+/* lseek.c */
+extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
+
+/* read.c */
+extern void blkid_read_cache(blkid_cache cache);
+
+/* save.c */
+extern int blkid_flush_cache(blkid_cache cache);
+
+/* cache */
+extern char *blkid_safe_getenv(const char *arg);
+extern char *blkid_get_cache_filename(struct blkid_config *conf);
+
+/*
+ * Functions to create and find a specific tag type: tag.c
+ */
+extern void blkid_free_tag(blkid_tag tag);
+extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type);
+extern int blkid_set_tag(blkid_dev dev, const char *name,
+ const char *value, const int vlength);
+
+/*
+ * Functions to create and find a specific tag type: dev.c
+ */
+extern blkid_dev blkid_new_dev(void);
+extern void blkid_free_dev(blkid_dev dev);
+
+/* probe.c */
+unsigned char *blkid_probe_get_buffer(blkid_probe pr,
+ blkid_loff_t off, blkid_loff_t len);
+
+/* returns superblok according to 'struct blkid_idmag' */
+#define blkid_probe_get_sb(_pr, _mag, type) \
+ ((type *) blkid_probe_get_buffer((_pr),\
+ (_mag)->kboff << 10, sizeof(type)))
+
+extern int blkid_probe_set_value(blkid_probe pr, const char *name,
+ unsigned char *data, size_t len);
+extern int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
+ const char *fmt, va_list ap);
+extern int blkid_probe_set_version(blkid_probe pr, const char *version);
+extern int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+extern int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len);
+extern int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
+ size_t len, int enc);
+extern int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
+ size_t len, const char *fmt, ...)
+ __attribute__ ((format (printf, 4, 5)));
+extern int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len);
+
+extern int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid);
+extern int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name);
+
+#define BLKID_ENC_UTF16BE 0
+#define BLKID_ENC_UTF16LE 1
+
+#endif /* _BLKID_BLKIDP_H */
diff --git a/shlibs/blkid/src/cache.c b/shlibs/blkid/src/cache.c
new file mode 100644
index 000000000..01e4be061
--- /dev/null
+++ b/shlibs/blkid/src/cache.c
@@ -0,0 +1,243 @@
+/*
+ * cache.c - allocation/initialization/free routines for cache
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#else
+#define PR_GET_DUMPABLE 3
+#endif
+#if (!defined(HAVE_PRCTL) && defined(linux))
+#include <sys/syscall.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include "blkidP.h"
+
+int blkid_debug_mask = 0;
+
+
+char *blkid_safe_getenv(const char *arg)
+{
+ if ((getuid() != geteuid()) || (getgid() != getegid()))
+ return NULL;
+#if HAVE_PRCTL
+ if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
+ return NULL;
+#else
+#if (defined(linux) && defined(SYS_prctl))
+ if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
+ return NULL;
+#endif
+#endif
+
+#ifdef HAVE___SECURE_GETENV
+ return __secure_getenv(arg);
+#else
+ return getenv(arg);
+#endif
+}
+
+#if 0 /* ifdef CONFIG_BLKID_DEBUG */
+static blkid_debug_dump_cache(int mask, blkid_cache cache)
+{
+ struct list_head *p;
+
+ if (!cache) {
+ printf("cache: NULL\n");
+ return;
+ }
+
+ printf("cache: time = %lu\n", cache->bic_time);
+ printf("cache: flags = 0x%08X\n", cache->bic_flags);
+
+ list_for_each(p, &cache->bic_devs) {
+ blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
+ blkid_debug_dump_dev(dev);
+ }
+}
+#endif
+
+#ifdef CONFIG_BLKID_DEBUG
+void blkid_init_debug(int mask)
+{
+ if (blkid_debug_mask & DEBUG_INIT)
+ return;
+
+ if (!mask)
+ {
+ char *dstr = getenv("BLKID_DEBUG");
+
+ if (dstr)
+ blkid_debug_mask = strtoul(dstr, 0, 0);
+ } else
+ blkid_debug_mask = mask;
+
+ if (blkid_debug_mask)
+ printf("libblkid: debug mask set to 0x%04x.\n", blkid_debug_mask);
+
+ blkid_debug_mask |= DEBUG_INIT;
+}
+#endif
+
+/* returns allocated path to cache */
+char *blkid_get_cache_filename(struct blkid_config *conf)
+{
+ char *filename;
+
+ filename = blkid_safe_getenv("BLKID_FILE");
+ if (filename)
+ filename = blkid_strdup(filename);
+ else if (conf)
+ filename = blkid_strdup(conf->cachefile);
+ else {
+ struct blkid_config *c = blkid_read_config(NULL);
+ if (!c)
+ filename = blkid_strdup(BLKID_CONFIG_FILE);
+ else {
+ filename = c->cachefile; /* already allocated */
+ c->cachefile = NULL;
+ blkid_free_config(c);
+ }
+ }
+ return filename;
+}
+
+int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
+{
+ blkid_cache cache;
+
+ blkid_init_debug(0);
+
+ DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
+ filename ? filename : "default cache"));
+
+ if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
+ return -BLKID_ERR_MEM;
+
+ INIT_LIST_HEAD(&cache->bic_devs);
+ INIT_LIST_HEAD(&cache->bic_tags);
+
+ if (filename && !*filename)
+ filename = NULL;
+ if (filename)
+ cache->bic_filename = blkid_strdup(filename);
+ else
+ cache->bic_filename = blkid_get_cache_filename(NULL);
+
+ blkid_read_cache(cache);
+ *ret_cache = cache;
+ return 0;
+}
+
+void blkid_put_cache(blkid_cache cache)
+{
+ if (!cache)
+ return;
+
+ (void) blkid_flush_cache(cache);
+
+ DBG(DEBUG_CACHE, printf("freeing cache struct\n"));
+
+ /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */
+
+ while (!list_empty(&cache->bic_devs)) {
+ blkid_dev dev = list_entry(cache->bic_devs.next,
+ struct blkid_struct_dev,
+ bid_devs);
+ blkid_free_dev(dev);
+ }
+
+ while (!list_empty(&cache->bic_tags)) {
+ blkid_tag tag = list_entry(cache->bic_tags.next,
+ struct blkid_struct_tag,
+ bit_tags);
+
+ while (!list_empty(&tag->bit_names)) {
+ blkid_tag bad = list_entry(tag->bit_names.next,
+ struct blkid_struct_tag,
+ bit_names);
+
+ DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
+ bad->bit_name, bad->bit_val));
+ blkid_free_tag(bad);
+ }
+ blkid_free_tag(tag);
+ }
+ free(cache->bic_filename);
+
+ free(cache);
+}
+
+void blkid_gc_cache(blkid_cache cache)
+{
+ struct list_head *p, *pnext;
+ struct stat st;
+
+ if (!cache)
+ return;
+
+ list_for_each_safe(p, pnext, &cache->bic_devs) {
+ blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
+ if (!p)
+ break;
+ if (stat(dev->bid_name, &st) < 0) {
+ DBG(DEBUG_CACHE,
+ printf("freeing %s\n", dev->bid_name));
+ blkid_free_dev(dev);
+ cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+ } else {
+ DBG(DEBUG_CACHE,
+ printf("Device %s exists\n", dev->bid_name));
+ }
+ }
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char** argv)
+{
+ blkid_cache cache = NULL;
+ int ret;
+
+ blkid_init_debug(DEBUG_ALL);
+
+ if ((argc > 2)) {
+ fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
+ exit(1);
+ }
+
+ if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
+ fprintf(stderr, "error %d parsing cache file %s\n", ret,
+ argv[1] ? argv[1] : BLKID_CACHE_FILE);
+ exit(1);
+ }
+ if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+ if ((ret = blkid_probe_all(cache) < 0))
+ fprintf(stderr, "error probing devices\n");
+
+ blkid_put_cache(cache);
+
+ return ret;
+}
+#endif
diff --git a/shlibs/blkid/src/config.c b/shlibs/blkid/src/config.c
new file mode 100644
index 000000000..9091736be
--- /dev/null
+++ b/shlibs/blkid/src/config.c
@@ -0,0 +1,205 @@
+/*
+ * config.c - blkid.conf routines
+ *
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdint.h>
+#include <stdarg.h>
+
+#include "blkdev.h"
+#include "blkidP.h"
+
+
+static int parse_evaluate(struct blkid_config *conf, char *s)
+{
+ while(s && *s) {
+ char *sep;
+
+ if (conf->nevals >= __BLKID_EVAL_LAST)
+ goto err;
+ sep = strchr(s, ',');
+ if (sep)
+ *sep = '\0';
+ if (strcmp(s, "udev") == 0)
+ conf->eval[conf->nevals] = BLKID_EVAL_UDEV;
+ else if (strcmp(s, "scan") == 0)
+ conf->eval[conf->nevals] = BLKID_EVAL_SCAN;
+ else
+ goto err;
+ conf->nevals++;
+ if (sep)
+ s = sep + 1;
+ else
+ break;
+ }
+ return 0;
+err:
+ DBG(DEBUG_CONFIG, printf(
+ "config file: unknown evaluation method '%s'.\n", s));
+ return -1;
+}
+
+static int parse_next(FILE *fd, struct blkid_config *conf)
+{
+ char buf[BUFSIZ];
+ char *s;
+
+ /* read the next non-blank non-comment line */
+ do {
+ if (fgets (buf, sizeof(buf), fd) == NULL)
+ return feof(fd) ? 0 : -1;
+ s = index (buf, '\n');
+ if (!s) {
+ /* Missing final newline? Otherwise extremely */
+ /* long line - assume file was corrupted */
+ if (feof(fd))
+ s = index (buf, '\0');
+ else {
+ DBG(DEBUG_CONFIG, fprintf(stderr,
+ "libblkid: config file: missing newline at line '%s'.\n",
+ buf));
+ return -1;
+ }
+ }
+ *s = '\0';
+ if (--s >= buf && *s == '\r')
+ *s = '\0';
+
+ s = buf;
+ while (*s == ' ' || *s == '\t') /* skip space */
+ s++;
+
+ } while (*s == '\0' || *s == '#');
+
+ if (!strncmp(s, "SEND_UEVENT=", 12)) {
+ s += 13;
+ if (*s && !strcasecmp(s, "yes"))
+ conf->uevent = TRUE;
+ else if (*s)
+ conf->uevent = FALSE;
+ } else if (!strncmp(s, "CACHE_FILE=", 11)) {
+ s += 11;
+ if (*s)
+ conf->cachefile = blkid_strdup(s);
+ } else if (!strncmp(s, "EVALUATE=", 9)) {
+ s += 9;
+ if (*s && parse_evaluate(conf, s) == -1)
+ return -1;
+ } else {
+ DBG(DEBUG_CONFIG, printf(
+ "config file: unknown option '%s'.\n", s));
+ return -1;
+ }
+ return 0;
+}
+
+/* return real config data or built-in default */
+struct blkid_config *blkid_read_config(const char *filename)
+{
+ struct blkid_config *conf;
+ FILE *f;
+
+ if (!filename)
+ filename = blkid_safe_getenv("BLKID_CONF");
+ if (!filename)
+ filename = BLKID_CONFIG_FILE;
+
+ conf = (struct blkid_config *) calloc(1, sizeof(*conf));
+ if (!conf)
+ return NULL;
+ conf->uevent = -1;
+
+ DBG(DEBUG_CONFIG, fprintf(stderr,
+ "reading config file: %s.\n", filename));
+
+ f = fopen(filename, "r");
+ if (!f) {
+ DBG(DEBUG_CONFIG, fprintf(stderr,
+ "%s: does not exist, using built-in default\n", filename));
+ goto dflt;
+ }
+ while (!feof(f)) {
+ if (parse_next(f, conf)) {
+ DBG(DEBUG_CONFIG, fprintf(stderr,
+ "%s: parse error\n", filename));
+ goto err;
+ }
+ }
+dflt:
+ if (!conf->nevals) {
+ conf->eval[0] = BLKID_EVAL_UDEV;
+ conf->eval[1] = BLKID_EVAL_SCAN;
+ conf->nevals = 2;
+ }
+ if (!conf->cachefile)
+ conf->cachefile = blkid_strdup(BLKID_CACHE_FILE);
+ if (conf->uevent == -1)
+ conf->uevent = TRUE;
+ if (f)
+ fclose(f);
+ return conf;
+err:
+ free(conf);
+ fclose(f);
+ return NULL;
+}
+
+void blkid_free_config(struct blkid_config *conf)
+{
+ if (!conf)
+ return;
+ free(conf->cachefile);
+ free(conf);
+}
+
+#ifdef TEST_PROGRAM
+/*
+ * usage: tst_config [<filename>]
+ */
+int main(int argc, char *argv[])
+{
+ int i;
+ struct blkid_config *conf;
+ char *filename = NULL;
+
+ blkid_init_debug(DEBUG_ALL);
+
+ if (argc == 2)
+ filename = argv[1];
+
+ conf = blkid_read_config(filename);
+ if (!conf)
+ return EXIT_FAILURE;
+
+ printf("EVALUATE: ");
+ for (i = 0; i < conf->nevals; i++)
+ printf("%s ", conf->eval[i] == BLKID_EVAL_UDEV ? "udev" : "scan");
+ printf("\n");
+
+ printf("SEND UEVENT: %s\n", conf->uevent ? "TRUE" : "FALSE");
+ printf("CACHE_FILE: %s\n", conf->cachefile);
+
+ blkid_free_config(conf);
+ return EXIT_SUCCESS;
+}
+#endif
diff --git a/shlibs/blkid/src/dev.c b/shlibs/blkid/src/dev.c
new file mode 100644
index 000000000..31b9fe86f
--- /dev/null
+++ b/shlibs/blkid/src/dev.c
@@ -0,0 +1,255 @@
+/*
+ * dev.c - allocation/initialization/free routines for dev
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "blkidP.h"
+
+blkid_dev blkid_new_dev(void)
+{
+ blkid_dev dev;
+
+ if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev))))
+ return NULL;
+
+ INIT_LIST_HEAD(&dev->bid_devs);
+ INIT_LIST_HEAD(&dev->bid_tags);
+
+ return dev;
+}
+
+void blkid_free_dev(blkid_dev dev)
+{
+ if (!dev)
+ return;
+
+ DBG(DEBUG_DEV,
+ printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ?
+ dev->bid_type : "(null)"));
+ DBG(DEBUG_DEV, blkid_debug_dump_dev(dev));
+
+ list_del(&dev->bid_devs);
+ while (!list_empty(&dev->bid_tags)) {
+ blkid_tag tag = list_entry(dev->bid_tags.next,
+ struct blkid_struct_tag,
+ bit_tags);
+ blkid_free_tag(tag);
+ }
+ free(dev->bid_name);
+ free(dev);
+}
+
+/*
+ * Given a blkid device, return its name
+ */
+extern const char *blkid_dev_devname(blkid_dev dev)
+{
+ return dev->bid_name;
+}
+
+#ifdef CONFIG_BLKID_DEBUG
+void blkid_debug_dump_dev(blkid_dev dev)
+{
+ struct list_head *p;
+
+ if (!dev) {
+ printf(" dev: NULL\n");
+ return;
+ }
+
+ printf(" dev: name = %s\n", dev->bid_name);
+ printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
+ printf(" dev: TIME=\"%ld\"\n", (long)dev->bid_time);
+ printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
+ printf(" dev: flags = 0x%08X\n", dev->bid_flags);
+
+ list_for_each(p, &dev->bid_tags) {
+ blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
+ if (tag)
+ printf(" tag: %s=\"%s\"\n", tag->bit_name,
+ tag->bit_val);
+ else
+ printf(" tag: NULL\n");
+ }
+ printf("\n");
+}
+#endif
+
+/*
+ * dev iteration routines for the public libblkid interface.
+ *
+ * These routines do not expose the list.h implementation, which are a
+ * contamination of the namespace, and which force us to reveal far, far
+ * too much of our internal implemenation. I'm not convinced I want
+ * to keep list.h in the long term, anyway. It's fine for kernel
+ * programming, but performance is not the #1 priority for this
+ * library, and I really don't like the tradeoff of type-safety for
+ * performance for this application. [tytso:20030125.2007EST]
+ */
+
+/*
+ * This series of functions iterate over all devices in a blkid cache
+ */
+#define DEV_ITERATE_MAGIC 0x01a5284c
+
+struct blkid_struct_dev_iterate {
+ int magic;
+ blkid_cache cache;
+ char *search_type;
+ char *search_value;
+ struct list_head *p;
+};
+
+extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
+{
+ blkid_dev_iterate iter;
+
+ iter = malloc(sizeof(struct blkid_struct_dev_iterate));
+ if (iter) {
+ iter->magic = DEV_ITERATE_MAGIC;
+ iter->cache = cache;
+ iter->p = cache->bic_devs.next;
+ iter->search_type = 0;
+ iter->search_value = 0;
+ }
+ return (iter);
+}
+
+extern int blkid_dev_set_search(blkid_dev_iterate iter,
+ char *search_type, char *search_value)
+{
+ char *new_type, *new_value;
+
+ if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type ||
+ !search_value)
+ return -1;
+ new_type = malloc(strlen(search_type)+1);
+ new_value = malloc(strlen(search_value)+1);
+ if (!new_type || !new_value) {
+ free(new_type);
+ free(new_value);
+ return -1;
+ }
+ strcpy(new_type, search_type);
+ strcpy(new_value, search_value);
+ free(iter->search_type);
+ free(iter->search_value);
+ iter->search_type = new_type;
+ iter->search_value = new_value;
+ return 0;
+}
+
+/*
+ * Return 0 on success, -1 on error
+ */
+extern int blkid_dev_next(blkid_dev_iterate iter,
+ blkid_dev *ret_dev)
+{
+ blkid_dev dev;
+
+ *ret_dev = 0;
+ if (!iter || iter->magic != DEV_ITERATE_MAGIC)
+ return -1;
+ while (iter->p != &iter->cache->bic_devs) {
+ dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
+ iter->p = iter->p->next;
+ if (iter->search_type &&
+ !blkid_dev_has_tag(dev, iter->search_type,
+ iter->search_value))
+ continue;
+ *ret_dev = dev;
+ return 0;
+ }
+ return -1;
+}
+
+extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
+{
+ if (!iter || iter->magic != DEV_ITERATE_MAGIC)
+ return;
+ iter->magic = 0;
+ free(iter);
+}
+
+#ifdef TEST_PROGRAM
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern char *optarg;
+extern int optind;
+#endif
+
+void usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog);
+ fprintf(stderr, "\tList all devices and exit\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ blkid_dev_iterate iter;
+ blkid_cache cache = NULL;
+ blkid_dev dev;
+ int c, ret;
+ char *tmp;
+ char *file = NULL;
+ char *search_type = NULL;
+ char *search_value = NULL;
+
+ while ((c = getopt (argc, argv, "m:f:")) != EOF)
+ switch (c) {
+ case 'f':
+ file = optarg;
+ break;
+ case 'm':
+ {
+ int mask = strtoul (optarg, &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, "Invalid debug mask: %s\n",
+ optarg);
+ exit(1);
+ }
+ blkid_init_debug(mask);
+ break;
+ }
+ case '?':
+ usage(argv[0]);
+ }
+ if (argc >= optind+2) {
+ search_type = argv[optind];
+ search_value = argv[optind+1];
+ optind += 2;
+ }
+ if (argc != optind)
+ usage(argv[0]);
+
+ if ((ret = blkid_get_cache(&cache, file)) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+
+ iter = blkid_dev_iterate_begin(cache);
+ if (search_type)
+ blkid_dev_set_search(iter, search_type, search_value);
+ while (blkid_dev_next(iter, &dev) == 0) {
+ printf("Device: %s\n", blkid_dev_devname(dev));
+ }
+ blkid_dev_iterate_end(iter);
+
+
+ blkid_put_cache(cache);
+ return (0);
+}
+#endif
diff --git a/shlibs/blkid/src/devname.c b/shlibs/blkid/src/devname.c
new file mode 100644
index 000000000..ef686f4b4
--- /dev/null
+++ b/shlibs/blkid/src/devname.c
@@ -0,0 +1,558 @@
+/*
+ * devname.c - get a dev by its device inode name
+ *
+ * Copyright (C) Andries Brouwer
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
+ * Copyright (C) 2001 Andreas Dilger
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#define _GNU_SOURCE 1
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <dirent.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+#include <time.h>
+
+#include "blkidP.h"
+
+/*
+ * Find a dev struct in the cache by device name, if available.
+ *
+ * If there is no entry with the specified device name, and the create
+ * flag is set, then create an empty device entry.
+ */
+blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
+{
+ blkid_dev dev = NULL, tmp;
+ struct list_head *p, *pnext;
+
+ if (!cache || !devname)
+ return NULL;
+
+ list_for_each(p, &cache->bic_devs) {
+ tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
+ if (strcmp(tmp->bid_name, devname))
+ continue;
+
+ DBG(DEBUG_DEVNAME,
+ printf("found devname %s in cache\n", tmp->bid_name));
+ dev = tmp;
+ break;
+ }
+
+ if (!dev && (flags & BLKID_DEV_CREATE)) {
+ if (access(devname, F_OK) < 0)
+ return NULL;
+ dev = blkid_new_dev();
+ if (!dev)
+ return NULL;
+ dev->bid_time = INT_MIN;
+ dev->bid_name = blkid_strdup(devname);
+ dev->bid_cache = cache;
+ list_add_tail(&dev->bid_devs, &cache->bic_devs);
+ cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+ }
+
+ if (flags & BLKID_DEV_VERIFY) {
+ dev = blkid_verify(cache, dev);
+ if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED))
+ return dev;
+ /*
+ * If the device is verified, then search the blkid
+ * cache for any entries that match on the type, uuid,
+ * and label, and verify them; if a cache entry can
+ * not be verified, then it's stale and so we remove
+ * it.
+ */
+ list_for_each_safe(p, pnext, &cache->bic_devs) {
+ blkid_dev dev2;
+ if (!p)
+ break;
+ dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
+ if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
+ continue;
+ if (!dev->bid_type || !dev2->bid_type ||
+ strcmp(dev->bid_type, dev2->bid_type))
+ continue;
+ if (dev->bid_label && dev2->bid_label &&
+ strcmp(dev->bid_label, dev2->bid_label))
+ continue;
+ if (dev->bid_uuid && dev2->bid_uuid &&
+ strcmp(dev->bid_uuid, dev2->bid_uuid))
+ continue;
+ if ((dev->bid_label && !dev2->bid_label) ||
+ (!dev->bid_label && dev2->bid_label) ||
+ (dev->bid_uuid && !dev2->bid_uuid) ||
+ (!dev->bid_uuid && dev2->bid_uuid))
+ continue;
+ dev2 = blkid_verify(cache, dev2);
+ if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED))
+ blkid_free_dev(dev2);
+ }
+ }
+ return dev;
+}
+
+/* Directories where we will try to search for device names */
+static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL };
+
+static int is_dm_leaf(const char *devname)
+{
+ struct dirent *de, *d_de;
+ DIR *dir, *d_dir;
+ char path[256];
+ int ret = 1;
+
+ if ((dir = opendir("/sys/block")) == NULL)
+ return 0;
+ while ((de = readdir(dir)) != NULL) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
+ !strcmp(de->d_name, devname) ||
+ strncmp(de->d_name, "dm-", 3) ||
+ strlen(de->d_name) > sizeof(path)-32)
+ continue;
+ sprintf(path, "/sys/block/%s/slaves", de->d_name);
+ if ((d_dir = opendir(path)) == NULL)
+ continue;
+ while ((d_de = readdir(d_dir)) != NULL) {
+ if (!strcmp(d_de->d_name, devname)) {
+ ret = 0;
+ break;
+ }
+ }
+ closedir(d_dir);
+ if (!ret)
+ break;
+ }
+ closedir(dir);
+ return ret;
+}
+
+/*
+ * Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
+ * provides the real DM device names in /sys/block/<ptname>/dm/name
+ */
+static char *get_dm_name(const char *ptname)
+{
+ FILE *f;
+ size_t sz;
+ char path[256], name[256], *res = NULL;
+
+ snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
+ if ((f = fopen(path, "r")) == NULL)
+ return NULL;
+
+ /* read "<name>\n" from sysfs */
+ if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
+ name[sz - 1] = '\0';
+ snprintf(path, sizeof(path), "/dev/mapper/%s", name);
+ res = blkid_strdup(path);
+ }
+ fclose(f);
+ return res;
+}
+
+/*
+ * Probe a single block device to add to the device cache.
+ */
+static void probe_one(blkid_cache cache, const char *ptname,
+ dev_t devno, int pri, int only_if_new)
+{
+ blkid_dev dev = NULL;
+ struct list_head *p, *pnext;
+ const char **dir;
+ char *devname = NULL;
+
+ /* See if we already have this device number in the cache. */
+ list_for_each_safe(p, pnext, &cache->bic_devs) {
+ blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
+ bid_devs);
+ if (tmp->bid_devno == devno) {
+ if (only_if_new && !access(tmp->bid_name, F_OK))
+ return;
+ dev = blkid_verify(cache, tmp);
+ if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
+ break;
+ dev = 0;
+ }
+ }
+ if (dev && dev->bid_devno == devno)
+ goto set_pri;
+
+ /* Try to translate private device-mapper dm-<N> names
+ * to standard /dev/mapper/<name>.
+ */
+ if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
+ devname = get_dm_name(ptname);
+ if (!devname)
+ blkid__scan_dir("/dev/mapper", devno, 0, &devname);
+ if (devname)
+ goto get_dev;
+ }
+
+ /*
+ * Take a quick look at /dev/ptname for the device number. We check
+ * all of the likely device directories. If we don't find it, or if
+ * the stat information doesn't check out, use blkid_devno_to_devname()
+ * to find it via an exhaustive search for the device major/minor.
+ */
+ for (dir = dirlist; *dir; dir++) {
+ struct stat st;
+ char device[256];
+
+ sprintf(device, "%s/%s", *dir, ptname);
+ if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
+ dev->bid_devno == devno)
+ goto set_pri;
+
+ if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) &&
+ st.st_rdev == devno) {
+ devname = blkid_strdup(device);
+ goto get_dev;
+ }
+ }
+ /* Do a short-cut scan of /dev/mapper first */
+ if (!devname)
+ blkid__scan_dir("/dev/mapper", devno, 0, &devname);
+ if (!devname) {
+ devname = blkid_devno_to_devname(devno);
+ if (!devname)
+ return;
+ }
+
+get_dev:
+ dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
+ free(devname);
+
+set_pri:
+ if (dev) {
+ if (pri)
+ dev->bid_pri = pri;
+ else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) {
+ dev->bid_pri = BLKID_PRI_DM;
+ if (is_dm_leaf(ptname))
+ dev->bid_pri += 5;
+ } else if (!strncmp(ptname, "md", 2))
+ dev->bid_pri = BLKID_PRI_MD;
+ }
+ return;
+}
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define VG_DIR "/proc/lvm/VGs"
+
+/*
+ * This function initializes the UUID cache with devices from the LVM
+ * proc hierarchy. We currently depend on the names of the LVM
+ * hierarchy giving us the device structure in /dev. (XXX is this a
+ * safe thing to do?)
+ */
+#ifdef VG_DIR
+static dev_t lvm_get_devno(const char *lvm_device)
+{
+ FILE *lvf;
+ char buf[1024];
+ int ma, mi;
+ dev_t ret = 0;
+
+ DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
+ if ((lvf = fopen(lvm_device, "r")) == NULL) {
+ DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
+ strerror(errno)));
+ return 0;
+ }
+
+ while (fgets(buf, sizeof(buf), lvf)) {
+ if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
+ ret = makedev(ma, mi);
+ break;
+ }
+ }
+ fclose(lvf);
+
+ return ret;
+}
+
+static void lvm_probe_all(blkid_cache cache, int only_if_new)
+{
+ DIR *vg_list;
+ struct dirent *vg_iter;
+ int vg_len = strlen(VG_DIR);
+ dev_t dev;
+
+ if ((vg_list = opendir(VG_DIR)) == NULL)
+ return;
+
+ DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
+
+ while ((vg_iter = readdir(vg_list)) != NULL) {
+ DIR *lv_list;
+ char *vdirname;
+ char *vg_name;
+ struct dirent *lv_iter;
+
+ vg_name = vg_iter->d_name;
+ if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
+ continue;
+ vdirname = malloc(vg_len + strlen(vg_name) + 8);
+ if (!vdirname)
+ goto exit;
+ sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
+
+ lv_list = opendir(vdirname);
+ free(vdirname);
+ if (lv_list == NULL)
+ continue;
+
+ while ((lv_iter = readdir(lv_list)) != NULL) {
+ char *lv_name, *lvm_device;
+
+ lv_name = lv_iter->d_name;
+ if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
+ continue;
+
+ lvm_device = malloc(vg_len + strlen(vg_name) +
+ strlen(lv_name) + 8);
+ if (!lvm_device) {
+ closedir(lv_list);
+ goto exit;
+ }
+ sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
+ lv_name);
+ dev = lvm_get_devno(lvm_device);
+ sprintf(lvm_device, "%s/%s", vg_name, lv_name);
+ DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
+ lvm_device,
+ (unsigned int) dev));
+ probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
+ only_if_new);
+ free(lvm_device);
+ }
+ closedir(lv_list);
+ }
+exit:
+ closedir(vg_list);
+}
+#endif
+
+#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
+
+static int
+evms_probe_all(blkid_cache cache, int only_if_new)
+{
+ char line[100];
+ int ma, mi, sz, num = 0;
+ FILE *procpt;
+ char device[110];
+
+ procpt = fopen(PROC_EVMS_VOLUMES, "r");
+ if (!procpt)
+ return 0;
+ while (fgets(line, sizeof(line), procpt)) {
+ if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
+ &ma, &mi, &sz, device) != 4)
+ continue;
+
+ DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
+ device, ma, mi));
+
+ probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
+ only_if_new);
+ num++;
+ }
+ fclose(procpt);
+ return num;
+}
+
+/*
+ * Read the device data for all available block devices in the system.
+ */
+static int probe_all(blkid_cache cache, int only_if_new)
+{
+ FILE *proc;
+ char line[1024];
+ char ptname0[128], ptname1[128], *ptname = 0;
+ char *ptnames[2];
+ dev_t devs[2];
+ int ma, mi;
+ unsigned long long sz;
+ int lens[2] = { 0, 0 };
+ int which = 0, last = 0;
+ struct list_head *p, *pnext;
+
+ ptnames[0] = ptname0;
+ ptnames[1] = ptname1;
+
+ if (!cache)
+ return -BLKID_ERR_PARAM;
+
+ if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
+ time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
+ return 0;
+
+ blkid_read_cache(cache);
+ evms_probe_all(cache, only_if_new);
+#ifdef VG_DIR
+ lvm_probe_all(cache, only_if_new);
+#endif
+
+ proc = fopen(PROC_PARTITIONS, "r");
+ if (!proc)
+ return -BLKID_ERR_PROC;
+
+ while (fgets(line, sizeof(line), proc)) {
+ last = which;
+ which ^= 1;
+ ptname = ptnames[which];
+
+ if (sscanf(line, " %d %d %llu %128[^\n ]",
+ &ma, &mi, &sz, ptname) != 4)
+ continue;
+ devs[which] = makedev(ma, mi);
+
+ DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
+
+ /* Skip whole disk devs unless they have no partitions.
+ * If base name of device has changed, also
+ * check previous dev to see if it didn't have a partn.
+ * heuristic: partition name ends in a digit, & partition
+ * names contain whole device name as substring.
+ *
+ * Skip extended partitions.
+ * heuristic: size is 1
+ *
+ * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
+ */
+
+ lens[which] = strlen(ptname);
+
+ /* ends in a digit, clearly a partition, so check */
+ if (isdigit(ptname[lens[which] - 1])) {
+ DBG(DEBUG_DEVNAME,
+ printf("partition dev %s, devno 0x%04X\n",
+ ptname, (unsigned int) devs[which]));
+
+ if (sz > 1)
+ probe_one(cache, ptname, devs[which], 0,
+ only_if_new);
+ lens[which] = 0; /* mark as checked */
+ }
+
+ /*
+ * If last was a whole disk and we just found a partition
+ * on it, remove the whole-disk dev from the cache if
+ * it exists.
+ */
+ if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
+ list_for_each_safe(p, pnext, &cache->bic_devs) {
+ blkid_dev tmp;
+
+ /* find blkid dev for the whole-disk devno */
+ tmp = list_entry(p, struct blkid_struct_dev,
+ bid_devs);
+ if (tmp->bid_devno == devs[last]) {
+ DBG(DEBUG_DEVNAME,
+ printf("freeing %s\n",
+ tmp->bid_name));
+ blkid_free_dev(tmp);
+ cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+ break;
+ }
+ }
+ lens[last] = 0;
+ }
+ /*
+ * If last was not checked because it looked like a whole-disk
+ * dev, and the device's base name has changed,
+ * check last as well.
+ */
+ if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
+ DBG(DEBUG_DEVNAME,
+ printf("whole dev %s, devno 0x%04X\n",
+ ptnames[last], (unsigned int) devs[last]));
+ probe_one(cache, ptnames[last], devs[last], 0,
+ only_if_new);
+ lens[last] = 0;
+ }
+ }
+
+ /* Handle the last device if it wasn't partitioned */
+ if (lens[which])
+ probe_one(cache, ptname, devs[which], 0, only_if_new);
+
+ fclose(proc);
+ blkid_flush_cache(cache);
+ return 0;
+}
+
+int blkid_probe_all(blkid_cache cache)
+{
+ int ret;
+
+ DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
+ ret = probe_all(cache, 0);
+ cache->bic_time = time(0);
+ cache->bic_flags |= BLKID_BIC_FL_PROBED;
+ DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
+ return ret;
+}
+
+int blkid_probe_all_new(blkid_cache cache)
+{
+ int ret;
+
+ DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
+ ret = probe_all(cache, 1);
+ DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
+ return ret;
+}
+
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv)
+{
+ blkid_cache cache = NULL;
+ int ret;
+
+ blkid_init_debug(DEBUG_ALL);
+ if (argc != 1) {
+ fprintf(stderr, "Usage: %s\n"
+ "Probe all devices and exit\n", argv[0]);
+ exit(1);
+ }
+ if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+ if (blkid_probe_all(cache) < 0)
+ printf("%s: error probing devices\n", argv[0]);
+
+ blkid_put_cache(cache);
+ return (0);
+}
+#endif
diff --git a/shlibs/blkid/src/devno.c b/shlibs/blkid/src/devno.c
new file mode 100644
index 000000000..8ffdb835d
--- /dev/null
+++ b/shlibs/blkid/src/devno.c
@@ -0,0 +1,228 @@
+/*
+ * devno.c - find a particular device by its device number (major/minor)
+ *
+ * Copyright (C) 2000, 2001, 2003 Theodore Ts'o
+ * Copyright (C) 2001 Andreas Dilger
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <dirent.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+
+#include "blkidP.h"
+
+char *blkid_strndup(const char *s, int length)
+{
+ char *ret;
+
+ if (!s)
+ return NULL;
+
+ if (!length)
+ length = strlen(s);
+
+ ret = malloc(length + 1);
+ if (ret) {
+ strncpy(ret, s, length);
+ ret[length] = '\0';
+ }
+ return ret;
+}
+
+char *blkid_strdup(const char *s)
+{
+ return blkid_strndup(s, 0);
+}
+
+/*
+ * This function adds an entry to the directory list
+ */
+static void add_to_dirlist(const char *name, struct dir_list **list)
+{
+ struct dir_list *dp;
+
+ dp = malloc(sizeof(struct dir_list));
+ if (!dp)
+ return;
+ dp->name = blkid_strdup(name);
+ if (!dp->name) {
+ free(dp);
+ return;
+ }
+ dp->next = *list;
+ *list = dp;
+}
+
+/*
+ * This function frees a directory list
+ */
+static void free_dirlist(struct dir_list **list)
+{
+ struct dir_list *dp, *next;
+
+ for (dp = *list; dp; dp = next) {
+ next = dp->next;
+ free(dp->name);
+ free(dp);
+ }
+ *list = NULL;
+}
+
+void blkid__scan_dir(char *dirname, dev_t devno, struct dir_list **list,
+ char **devname)
+{
+ DIR *dir;
+ struct dirent *dp;
+ char path[1024];
+ int dirlen;
+ struct stat st;
+
+ if ((dir = opendir(dirname)) == NULL)
+ return;
+ dirlen = strlen(dirname) + 2;
+ while ((dp = readdir(dir)) != 0) {
+ if (dirlen + strlen(dp->d_name) >= sizeof(path))
+ continue;
+
+ if (dp->d_name[0] == '.' &&
+ ((dp->d_name[1] == 0) ||
+ ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
+ continue;
+
+ sprintf(path, "%s/%s", dirname, dp->d_name);
+ if (stat(path, &st) < 0)
+ continue;
+
+ if (S_ISBLK(st.st_mode) && st.st_rdev == devno) {
+ *devname = blkid_strdup(path);
+ DBG(DEBUG_DEVNO,
+ printf("found 0x%llx at %s (%p)\n", (long long)devno,
+ path, *devname));
+ break;
+ }
+ if (list && S_ISDIR(st.st_mode) && !lstat(path, &st) &&
+ S_ISDIR(st.st_mode))
+ add_to_dirlist(path, list);
+ }
+ closedir(dir);
+ return;
+}
+
+/* Directories where we will try to search for device numbers */
+static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL };
+
+/*
+ * This function finds the pathname to a block device with a given
+ * device number. It returns a pointer to allocated memory to the
+ * pathname on success, and NULL on failure.
+ */
+char *blkid_devno_to_devname(dev_t devno)
+{
+ struct dir_list *list = NULL, *new_list = NULL;
+ char *devname = NULL;
+ const char **dir;
+
+ /*
+ * Add the starting directories to search in reverse order of
+ * importance, since we are using a stack...
+ */
+ for (dir = devdirs; *dir; dir++)
+ add_to_dirlist(*dir, &list);
+
+ while (list) {
+ struct dir_list *current = list;
+
+ list = list->next;
+ DBG(DEBUG_DEVNO, printf("directory %s\n", current->name));
+ blkid__scan_dir(current->name, devno, &new_list, &devname);
+ free(current->name);
+ free(current);
+ if (devname)
+ break;
+ /*
+ * If we're done checking at this level, descend to
+ * the next level of subdirectories. (breadth-first)
+ */
+ if (list == NULL) {
+ list = new_list;
+ new_list = NULL;
+ }
+ }
+ free_dirlist(&list);
+ free_dirlist(&new_list);
+
+ if (!devname) {
+ DBG(DEBUG_DEVNO,
+ printf("blkid: couldn't find devno 0x%04lx\n",
+ (unsigned long) devno));
+ } else {
+ DBG(DEBUG_DEVNO,
+ printf("found devno 0x%04llx as %s\n", (long long)devno, devname));
+ }
+
+
+ return devname;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char** argv)
+{
+ char *devname, *tmp;
+ int major, minor;
+ dev_t devno;
+ const char *errmsg = "Couldn't parse %s: %s\n";
+
+ blkid_init_debug(DEBUG_ALL);
+ if ((argc != 2) && (argc != 3)) {
+ fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n"
+ "Resolve a device number to a device name\n",
+ argv[0], argv[0]);
+ exit(1);
+ }
+ if (argc == 2) {
+ devno = strtoul(argv[1], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "device number", argv[1]);
+ exit(1);
+ }
+ } else {
+ major = strtoul(argv[1], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "major number", argv[1]);
+ exit(1);
+ }
+ minor = strtoul(argv[2], &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, errmsg, "minor number", argv[2]);
+ exit(1);
+ }
+ devno = makedev(major, minor);
+ }
+ printf("Looking for device 0x%04llx\n", (long long)devno);
+ devname = blkid_devno_to_devname(devno);
+ free(devname);
+ return 0;
+}
+#endif
diff --git a/shlibs/blkid/src/encode.c b/shlibs/blkid/src/encode.c
new file mode 100644
index 000000000..d45a292e8
--- /dev/null
+++ b/shlibs/blkid/src/encode.c
@@ -0,0 +1,288 @@
+
+/*
+ * encode.c - string convertion routines (mostly for compatibility with
+ * udev/volume_id)
+ *
+ * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "blkdev.h"
+#include "blkidP.h"
+
+#define UDEV_ALLOWED_CHARS_INPUT "/ $%?,"
+
+/* count of characters used to encode one unicode char */
+static int utf8_encoded_expected_len(const char *str)
+{
+ unsigned char c = (unsigned char)str[0];
+
+ if (c < 0x80)
+ return 1;
+ if ((c & 0xe0) == 0xc0)
+ return 2;
+ if ((c & 0xf0) == 0xe0)
+ return 3;
+ if ((c & 0xf8) == 0xf0)
+ return 4;
+ if ((c & 0xfc) == 0xf8)
+ return 5;
+ if ((c & 0xfe) == 0xfc)
+ return 6;
+ return 0;
+}
+
+/* decode one unicode char */
+static int utf8_encoded_to_unichar(const char *str)
+{
+ int unichar;
+ int len;
+ int i;
+
+ len = utf8_encoded_expected_len(str);
+ switch (len) {
+ case 1:
+ return (int)str[0];
+ case 2:
+ unichar = str[0] & 0x1f;
+ break;
+ case 3:
+ unichar = (int)str[0] & 0x0f;
+ break;
+ case 4:
+ unichar = (int)str[0] & 0x07;
+ break;
+ case 5:
+ unichar = (int)str[0] & 0x03;
+ break;
+ case 6:
+ unichar = (int)str[0] & 0x01;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i = 1; i < len; i++) {
+ if (((int)str[i] & 0xc0) != 0x80)
+ return -1;
+ unichar <<= 6;
+ unichar |= (int)str[i] & 0x3f;
+ }
+
+ return unichar;
+}
+
+/* expected size used to encode one unicode char */
+static int utf8_unichar_to_encoded_len(int unichar)
+{
+ if (unichar < 0x80)
+ return 1;
+ if (unichar < 0x800)
+ return 2;
+ if (unichar < 0x10000)
+ return 3;
+ if (unichar < 0x200000)
+ return 4;
+ if (unichar < 0x4000000)
+ return 5;
+ return 6;
+}
+
+/* check if unicode char has a valid numeric range */
+static int utf8_unichar_valid_range(int unichar)
+{
+ if (unichar > 0x10ffff)
+ return 0;
+ if ((unichar & 0xfffff800) == 0xd800)
+ return 0;
+ if ((unichar > 0xfdcf) && (unichar < 0xfdf0))
+ return 0;
+ if ((unichar & 0xffff) == 0xffff)
+ return 0;
+ return 1;
+}
+
+/* validate one encoded unicode char and return its length */
+static int utf8_encoded_valid_unichar(const char *str)
+{
+ int len;
+ int unichar;
+ int i;
+
+ len = utf8_encoded_expected_len(str);
+ if (len == 0)
+ return -1;
+
+ /* ascii is valid */
+ if (len == 1)
+ return 1;
+
+ /* check if expected encoded chars are available */
+ for (i = 0; i < len; i++)
+ if ((str[i] & 0x80) != 0x80)
+ return -1;
+
+ unichar = utf8_encoded_to_unichar(str);
+
+ /* check if encoded length matches encoded value */
+ if (utf8_unichar_to_encoded_len(unichar) != len)
+ return -1;
+
+ /* check if value has valid range */
+ if (!utf8_unichar_valid_range(unichar))
+ return -1;
+
+ return len;
+}
+
+static int replace_whitespace(const char *str, char *to, size_t len)
+{
+ size_t i, j;
+
+ /* strip trailing whitespace */
+ len = strnlen(str, len);
+ while (len && isspace(str[len-1]))
+ len--;
+
+ /* strip leading whitespace */
+ i = 0;
+ while (isspace(str[i]) && (i < len))
+ i++;
+
+ j = 0;
+ while (i < len) {
+ /* substitute multiple whitespace with a single '_' */
+ if (isspace(str[i])) {
+ while (isspace(str[i]))
+ i++;
+ to[j++] = '_';
+ }
+ to[j++] = str[i++];
+ }
+ to[j] = '\0';
+ return 0;
+}
+
+static int is_whitelisted(char c, const char *white)
+{
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ strchr("#+-.:=@_", c) != NULL ||
+ (white != NULL && strchr(white, c) != NULL))
+ return 1;
+ return 0;
+}
+
+/* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */
+static int replace_chars(char *str, const char *white)
+{
+ size_t i = 0;
+ int replaced = 0;
+
+ while (str[i] != '\0') {
+ int len;
+
+ if (is_whitelisted(str[i], white)) {
+ i++;
+ continue;
+ }
+
+ /* accept hex encoding */
+ if (str[i] == '\\' && str[i+1] == 'x') {
+ i += 2;
+ continue;
+ }
+
+ /* accept valid utf8 */
+ len = utf8_encoded_valid_unichar(&str[i]);
+ if (len > 1) {
+ i += len;
+ continue;
+ }
+
+ /* if space is allowed, replace whitespace with ordinary space */
+ if (isspace(str[i]) && white != NULL && strchr(white, ' ') != NULL) {
+ str[i] = ' ';
+ i++;
+ replaced++;
+ continue;
+ }
+
+ /* everything else is replaced with '_' */
+ str[i] = '_';
+ i++;
+ replaced++;
+ }
+ return replaced;
+}
+
+/**
+ * blkid_encode_string:
+ * @str: input string to be encoded
+ * @str_enc: output string to store the encoded input string
+ * @len: maximum size of the output string, which may be
+ * four times as long as the input string
+ *
+ * Encode all potentially unsafe characters of a string to the
+ * corresponding hex value prefixed by '\x'.
+ *
+ * Returns: 0 if the entire string was copied, non-zero otherwise.
+ **/
+int blkid_encode_string(const char *str, char *str_enc, size_t len)
+{
+ size_t i, j;
+
+ if (str == NULL || str_enc == NULL || len == 0)
+ return -1;
+
+ str_enc[0] = '\0';
+ for (i = 0, j = 0; str[i] != '\0'; i++) {
+ int seqlen;
+
+ seqlen = utf8_encoded_valid_unichar(&str[i]);
+ if (seqlen > 1) {
+ memcpy(&str_enc[j], &str[i], seqlen);
+ j += seqlen;
+ i += (seqlen-1);
+ } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
+ sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
+ j += 4;
+ } else {
+ str_enc[j] = str[i];
+ j++;
+ }
+ if (j+3 >= len)
+ goto err;
+ }
+ str_enc[j] = '\0';
+ return 0;
+err:
+ return -1;
+}
+
+/**
+ * blkid_safe_string:
+ * @str: input string
+ * @str_safe: output string
+ * @len: size of output string
+ *
+ * Allows plain ascii, hex-escaping and valid utf8. Replaces all whitespaces
+ * with '_'.
+ */
+int blkid_safe_string(const char *str, char *str_safe, size_t len)
+{
+ replace_whitespace(str, str_safe, len);
+ replace_chars(str_safe, UDEV_ALLOWED_CHARS_INPUT);
+ return 0;
+}
diff --git a/shlibs/blkid/src/evaluate.c b/shlibs/blkid/src/evaluate.c
new file mode 100644
index 000000000..f0ae12669
--- /dev/null
+++ b/shlibs/blkid/src/evaluate.c
@@ -0,0 +1,264 @@
+/*
+ * evaluate.c - very high-level API to evaluate LABELs or UUIDs
+ *
+ * This is simular to blkid_get_devname() from resolve.c, but this
+ * API supports udev /dev/disk/by-{label,uuid} links.
+ *
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdint.h>
+#include <stdarg.h>
+
+#include "pathnames.h"
+#include "canonicalize.h"
+
+#include "blkdev.h"
+#include "blkidP.h"
+
+/* returns zero when the device has NAME=value (LABEL/UUID) */
+static int verify_tag(const char *devname, const char *name, const char *value)
+{
+ blkid_probe pr;
+ int fd = -1, rc = -1;
+ size_t len;
+ const char *data;
+
+ pr = blkid_new_probe();
+ if (!pr)
+ return -1;
+
+ blkid_probe_set_request(pr, BLKID_PROBREQ_LABEL | BLKID_PROBREQ_UUID);
+
+ fd = open(devname, O_RDONLY);
+ if (fd < 0)
+ goto done;
+ if (blkid_probe_set_device(pr, fd, 0, 0))
+ goto done;
+ rc = blkid_do_safeprobe(pr);
+ if (rc)
+ goto done;
+ rc = blkid_probe_lookup_value(pr, name, &data, &len);
+ if (!rc)
+ rc = memcmp(value, data, len);
+done:
+ DBG(DEBUG_EVALUATE, printf("%s: %s verification %s\n",
+ devname, name, rc == 0 ? "PASS" : "FAILED"));
+ if (fd >= 0)
+ close(fd);
+ blkid_free_probe(pr);
+ return rc;
+}
+
+/**
+ * blkid_send_uevent:
+ * @devname: absolute path to the device
+ *
+ * Returns -1 in case of failure, or 0 on success.
+ */
+int blkid_send_uevent(const char *devname, const char *action)
+{
+ char uevent[PATH_MAX];
+ struct stat st;
+ FILE *f;
+ int rc = -1;
+
+ DBG(DEBUG_EVALUATE, printf("%s: uevent '%s' requested\n", devname, action));
+
+ if (!devname || !action)
+ return -1;
+ if (stat(devname, &st) || !S_ISBLK(st.st_mode))
+ return -1;
+
+ snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent",
+ major(st.st_rdev), minor(st.st_rdev));
+
+ f = fopen(uevent, "w");
+ if (f) {
+ rc = 0;
+ if (fputs(action, f) >= 0)
+ rc = 0;
+ fclose(f);
+ }
+ DBG(DEBUG_EVALUATE, printf("%s: send uevent %s\n",
+ uevent, rc == 0 ? "SUCCES" : "FAILED"));
+ return rc;
+}
+
+static char *evaluate_by_udev(const char *token, const char *value, int uevent)
+{
+ char dev[PATH_MAX];
+ char *path = NULL;
+ size_t len;
+ struct stat st;
+
+ DBG(DEBUG_EVALUATE,
+ printf("evaluating by udev %s=%s\n", token, value));
+
+ if (!strcmp(token, "UUID"))
+ strcpy(dev, _PATH_DEV_BYUUID "/");
+ else if (!strcmp(token, "LABEL"))
+ strcpy(dev, _PATH_DEV_BYLABEL "/");
+ else {
+ DBG(DEBUG_EVALUATE,
+ printf("unsupported token %s\n", token));
+ return NULL; /* unsupported tag */
+ }
+
+ len = strlen(dev);
+ if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0)
+ return NULL;
+
+ DBG(DEBUG_EVALUATE,
+ printf("expected udev link: %s\n", dev));
+
+ if (stat(dev, &st))
+ goto failed; /* link or device does not exist */
+
+ if (!S_ISBLK(st.st_mode))
+ return NULL;
+
+ path = canonicalize_path(dev);
+ if (!path)
+ return NULL;
+
+ if (verify_tag(path, token, value))
+ goto failed;
+ return path;
+
+failed:
+ DBG(DEBUG_EVALUATE, printf("failed to evaluate by udev\n"));
+
+ if (uevent && path)
+ blkid_send_uevent(path, "change");
+ free(path);
+ return NULL;
+}
+
+static char *evaluate_by_scan(const char *token, const char *value,
+ blkid_cache *cache, struct blkid_config *conf)
+{
+ blkid_cache c = cache ? *cache : NULL;
+ char *res;
+
+ DBG(DEBUG_EVALUATE,
+ printf("evaluating by blkid scan %s=%s\n", token, value));
+
+ if (!c) {
+ char *cachefile = blkid_get_cache_filename(conf);
+ blkid_get_cache(&c, cachefile);
+ free(cachefile);
+ }
+ if (!c)
+ return NULL;
+
+ res = blkid_get_devname(c, token, value);
+
+ if (cache)
+ *cache = c;
+ else
+ blkid_put_cache(c);
+
+ return res;
+}
+
+/**
+ * blkid_evaluate_tag:
+ * @token: token name (e.g "LABEL" or "UUID")
+ * @value: token data
+ * @cache: pointer to cache (or NULL when you don't want to re-use the cache)
+ *
+ * Returns allocated string with device name.
+ */
+char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache)
+{
+ struct blkid_config *conf = NULL;
+ char *t = NULL, *v = NULL;
+ char *ret = NULL;
+ int i;
+
+ if (!token)
+ return NULL;
+
+ if (!cache || !*cache)
+ blkid_init_debug(0);
+
+ DBG(DEBUG_EVALUATE,
+ printf("evaluating %s%s%s\n", token, value ? "=" : "",
+ value ? value : ""));
+
+ if (!value) {
+ if (!strchr(token, '=')) {
+ ret = blkid_strdup(token);
+ goto out;
+ }
+ blkid_parse_tag_string(token, &t, &v);
+ if (!t || !v)
+ goto out;
+ token = t;
+ value = v;
+ }
+
+ conf = blkid_read_config(NULL);
+ if (!conf)
+ goto out;
+
+ for (i = 0; i < conf->nevals; i++) {
+ if (conf->eval[i] == BLKID_EVAL_UDEV)
+ ret = evaluate_by_udev(token, value, conf->uevent);
+ else if (conf->eval[i] == BLKID_EVAL_SCAN)
+ ret = evaluate_by_scan(token, value, cache, conf);
+ if (ret)
+ break;
+ }
+
+ DBG(DEBUG_EVALUATE,
+ printf("%s=%s evaluated as %s\n", token, value, ret));
+out:
+ blkid_free_config(conf);
+ free(t);
+ free(v);
+ return ret;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char *argv[])
+{
+ blkid_cache cache = NULL;
+ char *res;
+
+ if (argc < 3) {
+ fprintf(stderr, "usage: %s <token> <value>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ blkid_init_debug(0);
+
+ res = blkid_evaluate_tag(argv[1], argv[2], &cache);
+ if (res)
+ printf("%s\n", res);
+ if (cache)
+ blkid_put_cache(cache);
+
+ return res ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+#endif
diff --git a/shlibs/blkid/src/getsize.c b/shlibs/blkid/src/getsize.c
new file mode 100644
index 000000000..10ba7ecf3
--- /dev/null
+++ b/shlibs/blkid/src/getsize.c
@@ -0,0 +1,207 @@
+/*
+ * getsize.c --- get the size of a partition.
+ *
+ * Copyright (C) 1995, 1995 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+/* include this before sys/queues.h! */
+#include "blkidP.h"
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <fcntl.h>
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_LINUX_FD_H
+#include <linux/fd.h>
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+#include <sys/disklabel.h>
+#endif
+#ifdef HAVE_SYS_DISK_H
+#ifdef HAVE_SYS_QUEUE_H
+#include <sys/queue.h> /* for LIST_HEAD */
+#endif
+#include <sys/disk.h>
+#endif
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+
+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
+#define BLKGETSIZE _IO(0x12,96) /* return device size */
+#endif
+
+#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
+#endif
+
+#ifdef APPLE_DARWIN
+#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
+#endif /* APPLE_DARWIN */
+
+static int valid_offset(int fd, blkid_loff_t offset)
+{
+ char ch;
+
+ if (blkid_llseek(fd, offset, 0) < 0)
+ return 0;
+ if (read(fd, &ch, 1) < 1)
+ return 0;
+ return 1;
+}
+
+/*
+ * Returns the number of bytes in a partition
+ */
+blkid_loff_t blkid_get_dev_size(int fd)
+{
+ int valid_blkgetsize64 = 1;
+#ifdef __linux__
+ struct utsname ut;
+#endif
+ unsigned long long size64;
+ unsigned long size;
+ blkid_loff_t high, low;
+#ifdef FDGETPRM
+ struct floppy_struct this_floppy;
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+ int part = -1;
+ struct disklabel lab;
+ struct partition *pp;
+ char ch;
+ struct stat st;
+#endif /* HAVE_SYS_DISKLABEL_H */
+
+#ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */
+ if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
+ if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
+ && (size64 << 9 > 0xFFFFFFFF))
+ return 0; /* EFBIG */
+ return (blkid_loff_t) size64 << 9;
+ }
+#endif
+
+#ifdef BLKGETSIZE64
+#ifdef __linux__
+ if ((uname(&ut) == 0) &&
+ ((ut.release[0] == '2') && (ut.release[1] == '.') &&
+ (ut.release[2] < '6') && (ut.release[3] == '.')))
+ valid_blkgetsize64 = 0;
+#endif
+ if (valid_blkgetsize64 &&
+ ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
+ if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
+ && ((size64) > 0xFFFFFFFF))
+ return 0; /* EFBIG */
+ return size64;
+ }
+#endif
+
+#ifdef BLKGETSIZE
+ if (ioctl(fd, BLKGETSIZE, &size) >= 0)
+ return (blkid_loff_t)size << 9;
+#endif
+
+/* tested on FreeBSD 6.1-RELEASE i386 */
+#ifdef DIOCGMEDIASIZE
+ if (ioctl(fd, DIOCGMEDIASIZE, &size64) >= 0)
+ return (off_t)size64;
+#endif /* DIOCGMEDIASIZE */
+
+#ifdef FDGETPRM
+ if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
+ return (blkid_loff_t)this_floppy.size << 9;
+#endif
+#ifdef HAVE_SYS_DISKLABEL_H
+ /*
+ * This code works for FreeBSD 4.11 i386, except for the full device
+ * (such as /dev/ad0). It doesn't work properly for newer FreeBSD
+ * though. FreeBSD >= 5.0 should be covered by the DIOCGMEDIASIZE
+ * above however.
+ *
+ * Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw,
+ * character) devices, so we need to check for S_ISCHR, too.
+ */
+ if ((fstat(fd, &st) >= 0) && (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
+ part = st.st_rdev & 7;
+ if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
+ pp = &lab.d_partitions[part];
+ if (pp->p_size)
+ return pp->p_size << 9;
+ }
+#endif /* HAVE_SYS_DISKLABEL_H */
+ {
+#ifdef HAVE_FSTAT64
+ struct stat64 st;
+ if (fstat64(fd, &st) == 0)
+#else
+ struct stat st;
+ if (fstat(fd, &st) == 0)
+#endif
+ if (S_ISREG(st.st_mode))
+ return st.st_size;
+ }
+
+
+ /*
+ * OK, we couldn't figure it out by using a specialized ioctl,
+ * which is generally the best way. So do binary search to
+ * find the size of the partition.
+ */
+ low = 0;
+ for (high = 1024; valid_offset(fd, high); high *= 2)
+ low = high;
+ while (low < high - 1)
+ {
+ const blkid_loff_t mid = (low + high) / 2;
+
+ if (valid_offset(fd, mid))
+ low = mid;
+ else
+ high = mid;
+ }
+ return low + 1;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv)
+{
+ long long bytes;
+ int fd;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s device\n"
+ "Determine the size of a device\n", argv[0]);
+ return 1;
+ }
+
+ if ((fd = open(argv[1], O_RDONLY)) < 0)
+ perror(argv[0]);
+
+ bytes = blkid_get_dev_size(fd);
+ printf("Device %s has %Ld 1k blocks.\n", argv[1],
+ (unsigned long long) bytes >> 10);
+
+ return 0;
+}
+#endif
diff --git a/shlibs/blkid/src/list.h b/shlibs/blkid/src/list.h
new file mode 100644
index 000000000..c1cbfec59
--- /dev/null
+++ b/shlibs/blkid/src/list.h
@@ -0,0 +1,179 @@
+#if !defined(_BLKID_LIST_H) && !defined(LIST_HEAD)
+#define _BLKID_LIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __GNUC__
+#define _INLINE_ static __inline__
+#else /* For Watcom C */
+#define _INLINE_ static inline
+#endif
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+_INLINE_ void __list_add(struct list_head * add,
+ struct list_head * prev,
+ struct list_head * next)
+{
+ next->prev = add;
+ add->next = next;
+ add->prev = prev;
+ prev->next = add;
+}
+
+/**
+ * list_add - add a new entry
+ * @add: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+_INLINE_ void list_add(struct list_head *add, struct list_head *head)
+{
+ __list_add(add, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @add: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+_INLINE_ void list_add_tail(struct list_head *add, struct list_head *head)
+{
+ __list_add(add, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+_INLINE_ void __list_del(struct list_head * prev,
+ struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ *
+ * list_empty() on @entry does not return true after this, @entry is
+ * in an undefined state.
+ */
+_INLINE_ void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+_INLINE_ void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+_INLINE_ int list_empty(struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+_INLINE_ void list_splice(struct list_head *list, struct list_head *head)
+{
+ struct list_head *first = list->next;
+
+ if (first != list) {
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+/**
+ * list_for_each - iterate over elements in a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_safe - iterate over elements in a list, but don't dereference
+ * pos after the body is done (in case it is freed)
+ * @pos: the &struct list_head to use as a loop counter.
+ * @pnext: the &struct list_head to use as a pointer to the next item.
+ * @head: the head for your list (not included in iteration).
+ */
+#define list_for_each_safe(pos, pnext, head) \
+ for (pos = (head)->next, pnext = pos->next; pos != (head); \
+ pos = pnext, pnext = pos->next)
+
+#undef _INLINE_
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLKID_LIST_H */
diff --git a/shlibs/blkid/src/llseek.c b/shlibs/blkid/src/llseek.c
new file mode 100644
index 000000000..5bd0e5167
--- /dev/null
+++ b/shlibs/blkid/src/llseek.c
@@ -0,0 +1,142 @@
+/*
+ * llseek.c -- stub calling the llseek system call
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef __MSDOS__
+#include <io.h>
+#endif
+
+#include "blkidP.h"
+
+#ifdef __linux__
+
+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
+
+#define my_llseek lseek64
+
+#elif defined(HAVE_LLSEEK)
+#include <syscall.h>
+
+#ifndef HAVE_LLSEEK_PROTOTYPE
+extern long long llseek(int fd, long long offset, int origin);
+#endif
+
+#define my_llseek llseek
+
+#else /* ! HAVE_LLSEEK */
+
+#if SIZEOF_LONG == SIZEOF_LONG_LONG
+
+#define llseek lseek
+
+#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */
+
+#include <linux/unistd.h>
+
+#ifndef __NR__llseek
+#define __NR__llseek 140
+#endif
+
+#ifndef __i386__
+static int _llseek(unsigned int, unsigned long, unsigned long,
+ blkid_loff_t *, unsigned int);
+
+static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high,
+ unsigned long, offset_low, blkid_loff_t *, result,
+ unsigned int, origin)
+#endif
+
+static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin)
+{
+ blkid_loff_t result;
+ int retval;
+
+#ifndef __i386__
+ retval = _llseek(fd, ((unsigned long long) offset) >> 32,
+ ((unsigned long long)offset) & 0xffffffff,
+ &result, origin);
+#else
+ retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32,
+ ((unsigned long long)offset) & 0xffffffff,
+ &result, origin);
+#endif
+ return (retval == -1 ? (blkid_loff_t) retval : result);
+}
+
+#endif /* __alpha__ || __ia64__ */
+
+#endif /* HAVE_LLSEEK */
+
+blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence)
+{
+ blkid_loff_t result;
+ static int do_compat = 0;
+
+ if ((sizeof(off_t) >= sizeof(blkid_loff_t)) ||
+ (offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1))))
+ return lseek(fd, (off_t) offset, whence);
+
+ if (do_compat) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ result = my_llseek(fd, offset, whence);
+ if (result == -1 && errno == ENOSYS) {
+ /*
+ * Just in case this code runs on top of an old kernel
+ * which does not support the llseek system call
+ */
+ do_compat++;
+ errno = EOVERFLOW;
+ }
+ return result;
+}
+
+#else /* !linux */
+
+#ifndef EOVERFLOW
+#ifdef EXT2_ET_INVALID_ARGUMENT
+#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT
+#else
+#define EOVERFLOW 112
+#endif
+#endif
+
+blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin)
+{
+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
+ return lseek64 (fd, offset, origin);
+#else
+ if ((sizeof(off_t) < sizeof(blkid_loff_t)) &&
+ (offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ return lseek(fd, (off_t) offset, origin);
+#endif
+}
+
+#endif /* linux */
+
+
diff --git a/shlibs/blkid/src/probe.c b/shlibs/blkid/src/probe.c
new file mode 100644
index 000000000..0e4745aca
--- /dev/null
+++ b/shlibs/blkid/src/probe.c
@@ -0,0 +1,919 @@
+/*
+ * probe.c - reads tags (LABEL, UUID, FS type, ..) from a block device
+ *
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdint.h>
+#ifdef HAVE_LIBUUID
+#include <uuid/uuid.h>
+#endif
+#include <stdarg.h>
+
+#include "blkdev.h"
+#include "blkidP.h"
+#include "probers/probers.h"
+
+static const struct blkid_idinfo *idinfos[] =
+{
+ /* RAIDs */
+ &linuxraid_idinfo,
+ &ddfraid_idinfo,
+ &iswraid_idinfo,
+ &lsiraid_idinfo,
+ &viaraid_idinfo,
+ &silraid_idinfo,
+ &nvraid_idinfo,
+ &pdcraid_idinfo,
+ &highpoint45x_idinfo,
+ &highpoint37x_idinfo,
+ &adraid_idinfo,
+ &jmraid_idinfo,
+ &lvm2_idinfo,
+ &lvm1_idinfo,
+ &luks_idinfo,
+
+ /* Filesystems */
+ &vfat_idinfo,
+ &swsuspend_idinfo,
+ &swap_idinfo,
+ &xfs_idinfo,
+ &ext4dev_idinfo,
+ &ext4_idinfo,
+ &ext3_idinfo,
+ &ext2_idinfo,
+ &jbd_idinfo,
+ &reiser_idinfo,
+ &reiser4_idinfo,
+ &jfs_idinfo,
+ &udf_idinfo,
+ &iso9660_idinfo,
+ &zfs_idinfo,
+ &hfsplus_idinfo,
+ &hfs_idinfo,
+ &ufs_idinfo,
+ &hpfs_idinfo,
+ &sysv_idinfo,
+ &xenix_idinfo,
+ &ntfs_idinfo,
+ &cramfs_idinfo,
+ &romfs_idinfo,
+ &minix_idinfo,
+ &gfs_idinfo,
+ &gfs2_idinfo,
+ &ocfs_idinfo,
+ &ocfs2_idinfo,
+ &oracleasm_idinfo,
+ &vxfs_idinfo,
+ &squashfs_idinfo,
+ &netware_idinfo,
+ &btrfs_idinfo
+};
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+/* filter bitmap macros */
+#define blkid_bmp_wordsize (8 * sizeof(unsigned long))
+#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize))
+#define blkid_bmp_idx_byte(item) ((item) / blkid_bmp_wordsize)
+
+#define blkid_bmp_set_item(bmp, item) \
+ ((bmp)[ blkid_bmp_idx_byte(item) ] |= blkid_bmp_idx_bit(item))
+
+#define blkid_bmp_unset_item(bmp, item) \
+ ((bmp)[ bmp_idx_byte(item) ] &= ~bmp_idx_bit(item))
+
+#define blkid_bmp_get_item(bmp, item) \
+ ((bmp)[ blkid_bmp_idx_byte(item) ] & blkid_bmp_idx_bit(item))
+
+#define blkid_bmp_size(max_items) \
+ (((max_items) + blkid_bmp_wordsize) / blkid_bmp_wordsize)
+
+#define BLKID_FLTR_ITEMS ARRAY_SIZE(idinfos)
+#define BLKID_FLTR_SIZE blkid_bmp_size(BLKID_FLTR_ITEMS)
+
+
+static int blkid_probe_set_usage(blkid_probe pr, int usage);
+
+int blkid_known_fstype(const char *fstype)
+{
+ int i;
+
+ if (!fstype)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
+ const struct blkid_idinfo *id = idinfos[i];
+ if (strcmp(id->name, fstype) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Returns a pointer to the newly allocated probe struct
+ */
+blkid_probe blkid_new_probe(void)
+{
+ blkid_init_debug(0);
+ return calloc(1, sizeof(struct blkid_struct_probe));
+}
+
+/*
+ * Deallocates probe struct, buffers and all allocated
+ * data that are associated with this probing control struct.
+ */
+void blkid_free_probe(blkid_probe pr)
+{
+ if (!pr)
+ return;
+ free(pr->fltr);
+ free(pr->buf);
+ free(pr->sbbuf);
+ free(pr);
+}
+
+static void blkid_probe_reset_vals(blkid_probe pr)
+{
+ memset(pr->vals, 0, sizeof(pr->vals));
+ pr->nvals = 0;
+}
+
+void blkid_reset_probe(blkid_probe pr)
+{
+ if (!pr)
+ return;
+ DBG(DEBUG_LOWPROBE, printf("reseting blkid_probe\n"));
+ if (pr->buf)
+ memset(pr->buf, 0, pr->buf_max);
+ pr->buf_off = 0;
+ pr->buf_len = 0;
+ pr->idx = 0;
+ if (pr->sbbuf)
+ memset(pr->sbbuf, 0, BLKID_SB_BUFSIZ);
+ pr->sbbuf_len = 0;
+ blkid_probe_reset_vals(pr);
+}
+
+
+/*
+ * Note that we have two offsets:
+ *
+ * 1/ general device offset (pr->off), that's useful for example when we
+ * probe a partition from whole disk image:
+ * blkid-low --offset <partition_position> disk.img
+ *
+ * 2/ buffer offset (the 'off' argument), that useful for offsets in
+ * superbloks, ...
+ *
+ * That means never use lseek(fd, 0, SEEK_SET), the zero position is always
+ * pr->off, so lseek(fd, pr->off, SEEK_SET).
+ *
+ */
+unsigned char *blkid_probe_get_buffer(blkid_probe pr,
+ blkid_loff_t off, blkid_loff_t len)
+{
+ ssize_t ret_read = 0;
+
+ if (off < 0 || len < 0) {
+ DBG(DEBUG_LOWPROBE,
+ printf("unexpected offset or length of buffer requested\n"));
+ return NULL;
+ }
+ if (off + len <= BLKID_SB_BUFSIZ) {
+ if (!pr->sbbuf) {
+ pr->sbbuf = malloc(BLKID_SB_BUFSIZ);
+ if (!pr->sbbuf)
+ return NULL;
+ }
+ if (!pr->sbbuf_len) {
+ if (lseek(pr->fd, pr->off, SEEK_SET) < 0)
+ return NULL;
+ ret_read = read(pr->fd, pr->sbbuf, BLKID_SB_BUFSIZ);
+ if (ret_read < 0)
+ ret_read = 0;
+ pr->sbbuf_len = ret_read;
+ }
+ if (off + len > pr->sbbuf_len)
+ return NULL;
+ return pr->sbbuf + off;
+ } else {
+ unsigned char *newbuf = NULL;
+
+ if (len > pr->buf_max) {
+ newbuf = realloc(pr->buf, len);
+ if (!newbuf)
+ return NULL;
+ pr->buf = newbuf;
+ pr->buf_max = len;
+ pr->buf_off = 0;
+ pr->buf_len = 0;
+ }
+ if (newbuf || off < pr->buf_off ||
+ off + len > pr->buf_off + pr->buf_len) {
+
+ if (blkid_llseek(pr->fd, pr->off + off, SEEK_SET) < 0)
+ return NULL;
+
+ ret_read = read(pr->fd, pr->buf, len);
+ if (ret_read != (ssize_t) len)
+ return NULL;
+ pr->buf_off = off;
+ pr->buf_len = len;
+ }
+ return off ? pr->buf + (off - pr->buf_off) : pr->buf;
+ }
+}
+
+/*
+ * Assignes the device to probe control struct, resets internal buffers and
+ * reads 512 bytes from device to the buffers.
+ *
+ * Returns -1 in case of failure, or 0 on success.
+ */
+int blkid_probe_set_device(blkid_probe pr, int fd,
+ blkid_loff_t off, blkid_loff_t size)
+{
+ if (!pr)
+ return -1;
+
+ blkid_reset_probe(pr);
+
+ pr->fd = fd;
+ pr->off = off;
+ pr->size = 0;
+ pr->idx = 0;
+
+ if (size)
+ pr->size = size;
+ else {
+ struct stat sb;
+
+ if (fstat(fd, &sb))
+ return -1;
+
+ if (S_ISBLK(sb.st_mode))
+ blkdev_get_size(fd, (unsigned long long *) &pr->size);
+ else
+ pr->size = sb.st_size;
+ }
+ if (!pr->size)
+ return -1;
+
+ /* read SB to test if the device is readable */
+ if (!blkid_probe_get_buffer(pr, 0, 0x200)) {
+ DBG(DEBUG_LOWPROBE,
+ printf("failed to prepare a device for low-probing\n"));
+ return -1;
+ }
+
+ DBG(DEBUG_LOWPROBE, printf("ready for low-probing, offset=%zd, size=%zd\n",
+ pr->off, pr->size));
+ return 0;
+}
+
+int blkid_probe_set_request(blkid_probe pr, int flags)
+{
+ if (!pr)
+ return -1;
+ pr->probreq = flags;
+ return 0;
+}
+
+int blkid_probe_reset_filter(blkid_probe pr)
+{
+ if (!pr)
+ return -1;
+ if (pr->fltr)
+ memset(pr->fltr, 0, BLKID_FLTR_SIZE * sizeof(unsigned long));
+ pr->idx = 0;
+ return 0;
+}
+
+/*
+ * flag:
+ *
+ * BLKID_FLTR_NOTIN - probe all filesystems which are NOT IN names[]
+ *
+ * BLKID_FLTR_ONLYIN - probe filesystem which are IN names[]
+ */
+int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
+{
+ int i;
+
+ if (!pr || !names)
+ return -1;
+ if (!pr->fltr)
+ pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long));
+ else
+ blkid_probe_reset_filter(pr);
+
+ if (!pr->fltr)
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
+ int has = 0;
+ const struct blkid_idinfo *id = idinfos[i];
+ char **n;
+
+ for (n = names; *n; n++) {
+ if (!strcmp(id->name, *n)) {
+ has = 1;
+ break;
+ }
+ }
+ /* The default is enable all filesystems,
+ * set relevant bitmap bit means disable the filesystem.
+ */
+ if (flag & BLKID_FLTR_ONLYIN) {
+ if (!has)
+ blkid_bmp_set_item(pr->fltr, i);
+ } else if (flag & BLKID_FLTR_NOTIN) {
+ if (has)
+ blkid_bmp_set_item(pr->fltr, i);
+ }
+ }
+ DBG(DEBUG_LOWPROBE, printf("a new probing type-filter initialized\n"));
+ pr->idx = 0;
+ return 0;
+}
+
+/*
+ * flag:
+ *
+ * BLKID_FLTR_NOTIN - probe all filesystems which are NOT IN "usage"
+ *
+ * BLKID_FLTR_ONLYIN - probe filesystem which are IN "usage"
+ *
+ * where the "usage" is a set of filesystem according the usage flag (crypto,
+ * raid, filesystem, ...)
+ */
+int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
+{
+ int i;
+
+ if (!pr || !usage)
+ return -1;
+ if (!pr->fltr)
+ pr->fltr = calloc(BLKID_FLTR_SIZE, sizeof(unsigned long));
+ else
+ blkid_probe_reset_filter(pr);
+
+ if (!pr->fltr)
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
+ const struct blkid_idinfo *id = idinfos[i];
+
+ if (id->usage & usage) {
+ if (flag & BLKID_FLTR_NOTIN)
+ blkid_bmp_set_item(pr->fltr, i);
+ } else if (flag & BLKID_FLTR_ONLYIN)
+ blkid_bmp_set_item(pr->fltr, i);
+ }
+ DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n"));
+ pr->idx = 0;
+ return 0;
+}
+
+
+int blkid_probe_invert_filter(blkid_probe pr)
+{
+ int i;
+
+ if (!pr || !pr->fltr)
+ return -1;
+ for (i = 0; i < BLKID_FLTR_SIZE; i++)
+ pr->fltr[i] = ~pr->fltr[i];
+
+ DBG(DEBUG_LOWPROBE, printf("probing filter inverted\n"));
+ pr->idx = 0;
+ return 0;
+}
+
+/*
+ * The blkid_do_probe() calls the probe functions. This routine could be used
+ * in a loop when you need to probe for all possible filesystems/raids.
+ *
+ * 1/ basic case -- use the first result:
+ *
+ * if (blkid_do_probe(pr) == 0) {
+ * int nvals = blkid_probe_numof_values(pr);
+ * for (n = 0; n < nvals; n++) {
+ * if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
+ * printf("%s = %s\n", name, data);
+ * }
+ * }
+ *
+ * 2/ advanced case -- probe for all signatures (don't forget that some
+ * filesystems can co-exist on one volume (e.g. CD-ROM).
+ *
+ * while (blkid_do_probe(pr) == 0) {
+ * int nvals = blkid_probe_numof_values(pr);
+ * ...
+ * }
+ *
+ * The internal probing index (pointer to the last probing function) is
+ * always reseted when you touch probing filter or set a new device. It
+ * means you cannot use:
+ *
+ * blkid_probe_invert_filter()
+ * blkid_probe_filter_usage()
+ * blkid_probe_filter_types()
+ * blkid_probe_reset_filter()
+ * blkid_probe_set_device()
+ *
+ * in the loop (e.g while()) when you iterate on all signatures.
+ */
+int blkid_do_probe(blkid_probe pr)
+{
+ int i = 0;
+
+ if (!pr)
+ return -1;
+
+ blkid_probe_reset_vals(pr);
+
+ if (pr->idx)
+ i = pr->idx + 1;
+
+ if (i < 0 && i >= ARRAY_SIZE(idinfos))
+ return -1;
+
+ DBG(DEBUG_LOWPROBE, printf("--> starting probing loop\n"));
+
+ for ( ; i < ARRAY_SIZE(idinfos); i++) {
+ const struct blkid_idinfo *id;
+ const struct blkid_idmag *mag;
+ int hasmag = 0;
+
+ pr->idx = i;
+
+ if (pr->fltr && blkid_bmp_get_item(pr->fltr, i))
+ continue;
+
+ id = idinfos[i];
+ mag = id->magics ? &id->magics[0] : NULL;
+
+ /* try to detect by magic string */
+ while(mag && mag->magic) {
+ int idx;
+ unsigned char *buf;
+
+ idx = mag->kboff + (mag->sboff >> 10);
+ buf = blkid_probe_get_buffer(pr, idx << 10, 1024);
+
+ if (buf && !memcmp(mag->magic,
+ buf + (mag->sboff & 0x3ff), mag->len)) {
+ DBG(DEBUG_LOWPROBE, printf(
+ "%s: magic sboff=%u, kboff=%ld\n",
+ id->name, mag->sboff, mag->kboff));
+ hasmag = 1;
+ break;
+ }
+ mag++;
+ }
+
+ if (hasmag == 0 && id->magics && id->magics[0].magic)
+ /* magic string(s) defined, but not found */
+ continue;
+
+ /* final check by probing function */
+ if (id->probefunc) {
+ DBG(DEBUG_LOWPROBE, printf(
+ "%s: call probefunc()\n", id->name));
+ if (id->probefunc(pr, mag) != 0)
+ continue;
+ }
+
+ /* all cheks passed */
+ if (pr->probreq & BLKID_PROBREQ_TYPE)
+ blkid_probe_set_value(pr, "TYPE",
+ (unsigned char *) id->name,
+ strlen(id->name) + 1);
+ if (pr->probreq & BLKID_PROBREQ_USAGE)
+ blkid_probe_set_usage(pr, id->usage);
+
+ DBG(DEBUG_LOWPROBE,
+ printf("<-- leaving probing loop (type=%s)\n", id->name));
+ return 0;
+ }
+ DBG(DEBUG_LOWPROBE, printf("<-- leaving probing loop (failed)\n"));
+ return 1;
+}
+
+/*
+ * This is the same function as blkid_do_probe(), but returns only one result
+ * (cannot be used in while()) and checks for ambivalen results (more
+ * filesystems on the device) -- in such case returns -2.
+ */
+int blkid_do_safeprobe(blkid_probe pr)
+{
+ struct blkid_struct_probe first;
+ int count = 0;
+ int intol = 0;
+ int rc;
+
+ while ((rc = blkid_do_probe(pr)) == 0) {
+ if (!count) {
+ /* store the fist result */
+ memcpy(first.vals, pr->vals, sizeof(first.vals));
+ first.nvals = pr->nvals;
+ first.idx = pr->idx;
+ }
+ if (!(idinfos[pr->idx]->flags & BLKID_IDINFO_TOLERANT))
+ intol++;
+ count++;
+ }
+ if (rc < 0)
+ return rc; /* error */
+ if (count > 1 && intol) {
+ DBG(DEBUG_LOWPROBE,
+ printf("ERROR: ambivalent result detected (%d filesystems)!\n",
+ count));
+ return -2; /* error, ambivalent result (more FS) */
+ }
+ if (!count)
+ return 1; /* nothing detected */
+
+ /* restore the first result */
+ memcpy(pr->vals, first.vals, sizeof(first.vals));
+ pr->nvals = first.nvals;
+ pr->idx = first.idx;
+
+ return 0;
+}
+
+int blkid_probe_numof_values(blkid_probe pr)
+{
+ if (!pr)
+ return -1;
+ return pr->nvals;
+}
+
+
+static struct blkid_prval *blkid_probe_assign_value(
+ blkid_probe pr, const char *name)
+{
+ struct blkid_prval *v;
+
+ if (!name)
+ return NULL;
+ if (pr->nvals >= BLKID_PROBVAL_NVALS)
+ return NULL;
+
+ v = &pr->vals[pr->nvals];
+ v->name = name;
+ pr->nvals++;
+
+ DBG(DEBUG_LOWPROBE, printf("assigning %s\n", name));
+ return v;
+}
+
+int blkid_probe_set_value(blkid_probe pr, const char *name,
+ unsigned char *data, size_t len)
+{
+ struct blkid_prval *v;
+
+ if (len > BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ;
+
+ v = blkid_probe_assign_value(pr, name);
+ if (!v)
+ return -1;
+
+ memcpy(v->data, data, len);
+ v->len = len;
+ return 0;
+}
+
+int blkid_probe_vsprintf_value(blkid_probe pr, const char *name,
+ const char *fmt, va_list ap)
+{
+ struct blkid_prval *v;
+ size_t len;
+
+ v = blkid_probe_assign_value(pr, name);
+ if (!v)
+ return -1;
+
+ len = vsnprintf((char *) v->data, sizeof(v->data), fmt, ap);
+
+ if (len <= 0) {
+ pr->nvals--; /* reset the latest assigned value */
+ return -1;
+ }
+ v->len = len + 1;
+ return 0;
+}
+
+int blkid_probe_set_version(blkid_probe pr, const char *version)
+{
+ if (pr->probreq & BLKID_PROBREQ_VERSION)
+ return blkid_probe_set_value(pr, "VERSION",
+ (unsigned char *) version, strlen(version) + 1);
+ return 0;
+}
+
+int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
+{
+ int rc = 0;
+
+ if (pr->probreq & BLKID_PROBREQ_VERSION) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
+ va_end(ap);
+ }
+ return rc;
+}
+
+static int blkid_probe_set_usage(blkid_probe pr, int usage)
+{
+ char *u = NULL;
+
+ if (usage & BLKID_USAGE_FILESYSTEM)
+ u = "filesystem";
+ else if (usage & BLKID_USAGE_RAID)
+ u = "raid";
+ else if (usage & BLKID_USAGE_CRYPTO)
+ u = "crypto";
+ else if (usage & BLKID_USAGE_OTHER)
+ u = "other";
+ else
+ u = "unknown";
+
+ return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
+}
+
+int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
+{
+ struct blkid_prval *v;
+ int i;
+
+ if (len > BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ;
+
+ if ((pr->probreq & BLKID_PROBREQ_LABELRAW) &&
+ blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
+ return -1;
+ if (!(pr->probreq & BLKID_PROBREQ_LABEL))
+ return 0;
+ v = blkid_probe_assign_value(pr, "LABEL");
+ if (!v)
+ return -1;
+
+ memcpy(v->data, label, len);
+ v->data[len] = '\0';
+
+ /* remove trailing whitespace */
+ i = strnlen((char *) v->data, len);
+ while (i--) {
+ if (!isspace(v->data[i]))
+ break;
+ }
+ v->data[++i] = '\0';
+ v->len = i + 1;
+ return 0;
+}
+
+static size_t encode_to_utf8(int enc, unsigned char *dest, size_t len,
+ unsigned char *src, size_t count)
+{
+ size_t i, j;
+ uint16_t c;
+
+ for (j = i = 0; i + 2 <= count; i += 2) {
+ if (enc == BLKID_ENC_UTF16LE)
+ c = (src[i+1] << 8) | src[i];
+ else /* BLKID_ENC_UTF16BE */
+ c = (src[i] << 8) | src[i+1];
+ if (c == 0) {
+ dest[j] = '\0';
+ break;
+ } else if (c < 0x80) {
+ if (j+1 >= len)
+ break;
+ dest[j++] = (uint8_t) c;
+ } else if (c < 0x800) {
+ if (j+2 >= len)
+ break;
+ dest[j++] = (uint8_t) (0xc0 | (c >> 6));
+ dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
+ } else {
+ if (j+3 >= len)
+ break;
+ dest[j++] = (uint8_t) (0xe0 | (c >> 12));
+ dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
+ dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
+ }
+ }
+ dest[j] = '\0';
+ return j;
+}
+
+int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
+ size_t len, int enc)
+{
+ struct blkid_prval *v;
+
+ if ((pr->probreq & BLKID_PROBREQ_LABELRAW) &&
+ blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
+ return -1;
+ if (!(pr->probreq & BLKID_PROBREQ_LABEL))
+ return 0;
+ v = blkid_probe_assign_value(pr, "LABEL");
+ if (!v)
+ return -1;
+
+ v->len = encode_to_utf8(enc, v->data, sizeof(v->data), label, len);
+ return 0;
+}
+
+/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
+static int uuid_is_empty(const unsigned char *buf, size_t len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (buf[i])
+ return 0;
+ return 1;
+}
+
+int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
+ size_t len, const char *fmt, ...)
+{
+ int rc = -1;
+ va_list ap;
+
+ if (len > BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ;
+
+ if (uuid_is_empty(uuid, len))
+ return 0;
+
+ if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) &&
+ blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0)
+ return -1;
+ if (!(pr->probreq & BLKID_PROBREQ_UUID))
+ return 0;
+
+ va_start(ap, fmt);
+ rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
+ va_end(ap);
+
+ /* convert to lower case (..be paranoid) */
+ if (!rc) {
+ int i;
+ struct blkid_prval *v = &pr->vals[pr->nvals];
+
+ for (i = 0; i < v->len; i++)
+ if (v->data[i] >= 'A' && v->data[i] <= 'F')
+ v->data[i] = (v->data[i] - 'A') + 'a';
+ }
+ return rc;
+}
+
+/* function to set UUIDs that are in suberblocks stored as strings */
+int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len)
+{
+ struct blkid_prval *v;
+
+ if (str == NULL || *str == '\0')
+ return -1;
+ if (!len)
+ len = strlen((char *) str);
+ if (len > BLKID_PROBVAL_BUFSIZ)
+ len = BLKID_PROBVAL_BUFSIZ;
+
+ if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) &&
+ blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0)
+ return -1;
+ if (!(pr->probreq & BLKID_PROBREQ_UUID))
+ return 0;
+
+ v = blkid_probe_assign_value(pr, "UUID");
+ if (v) {
+ memcpy((char *) v->data, str, len);
+ *(v->data + len) = '\0';
+ v->len = len;
+ return 0;
+ }
+ return -1;
+}
+
+/* default _set_uuid function to set DCE UUIDs */
+int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
+{
+ struct blkid_prval *v;
+
+ if (uuid_is_empty(uuid, 16))
+ return 0;
+
+ if (!name) {
+ if ((pr->probreq & BLKID_PROBREQ_UUIDRAW) &&
+ blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0)
+ return -1;
+ if (!(pr->probreq & BLKID_PROBREQ_UUID))
+ return 0;
+
+ v = blkid_probe_assign_value(pr, "UUID");
+ } else
+ v = blkid_probe_assign_value(pr, name);
+
+#ifdef HAVE_LIBUUID
+ {
+ uuid_unparse(uuid, (char *) v->data);
+ v->len = 37;
+ }
+#else
+ v->len = snprintf(v->data, sizeof(v->data),
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5],
+ uuid[6], uuid[7],
+ uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
+ v->len++;
+#endif
+ return 0;
+}
+
+int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid)
+{
+ return blkid_probe_set_uuid_as(pr, uuid, NULL);
+}
+
+int blkid_probe_get_value(blkid_probe pr, int num, const char **name,
+ const char **data, size_t *len)
+{
+ struct blkid_prval *v;
+
+ if (pr == NULL || num < 0 || num >= pr->nvals)
+ return -1;
+
+ v = &pr->vals[num];
+ if (name)
+ *name = v->name;
+ if (data)
+ *data = (char *) v->data;
+ if (len)
+ *len = v->len;
+
+ DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
+ return 0;
+}
+
+int blkid_probe_lookup_value(blkid_probe pr, const char *name,
+ const char **data, size_t *len)
+{
+ int i;
+
+ if (pr == NULL || pr->nvals == 0 || name == NULL)
+ return -1;
+
+ for (i = 0; i < pr->nvals; i++) {
+ struct blkid_prval *v = &pr->vals[i];
+
+ if (v->name && strcmp(name, v->name) == 0) {
+ if (data)
+ *data = (char *) v->data;
+ if (len)
+ *len = v->len;
+ DBG(DEBUG_LOWPROBE, printf("returning %s value\n", v->name));
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int blkid_probe_has_value(blkid_probe pr, const char *name)
+{
+ if (blkid_probe_lookup_value(pr, name, NULL, NULL) == 0)
+ return 1;
+ return 0;
+}
+
diff --git a/shlibs/blkid/src/probers/Makefile.am b/shlibs/blkid/src/probers/Makefile.am
new file mode 100644
index 000000000..d8a98ed24
--- /dev/null
+++ b/shlibs/blkid/src/probers/Makefile.am
@@ -0,0 +1,43 @@
+include $(top_srcdir)/config/include-Makefile.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/libs/blkid/src
+
+noinst_LTLIBRARIES = libblkid_probers.la
+libblkid_probers_la_SOURCES = \
+ probers.h \
+ cramfs.c \
+ swap.c \
+ adaptec_raid.c \
+ ddf_raid.c \
+ isw_raid.c \
+ jmicron_raid.c \
+ lsi_raid.c \
+ nvidia_raid.c \
+ promise_raid.c \
+ silicon_raid.c \
+ via_raid.c \
+ linux_raid.c \
+ jfs.c \
+ xfs.c \
+ ext.c \
+ gfs.c \
+ ocfs.c \
+ reiserfs.c \
+ romfs.c \
+ ntfs.c \
+ hfs.c \
+ iso9660.c \
+ udf.c \
+ vfat.c \
+ luks.c \
+ highpoint_raid.c \
+ vxfs.c \
+ minix.c \
+ ufs.c \
+ hpfs.c \
+ squashfs.c \
+ netware.c \
+ sysv.c \
+ btrfs.c \
+ lvm.c \
+ zfs.c
diff --git a/shlibs/blkid/src/probers/adaptec_raid.c b/shlibs/blkid/src/probers/adaptec_raid.c
new file mode 100644
index 000000000..5e8b3a758
--- /dev/null
+++ b/shlibs/blkid/src/probers/adaptec_raid.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct adaptec_metadata {
+ uint32_t b0idcode;
+ uint8_t lunsave[8];
+ uint16_t sdtype;
+ uint16_t ssavecyl;
+ uint8_t ssavehed;
+ uint8_t ssavesec;
+ uint8_t sb0flags;
+ uint8_t jbodEnable;
+ uint8_t lundsave;
+ uint8_t svpdirty;
+ uint16_t biosInfo;
+ uint16_t svwbskip;
+ uint16_t svwbcln;
+ uint16_t svwbmax;
+ uint16_t res3;
+ uint16_t svwbmin;
+ uint16_t res4;
+ uint16_t svrcacth;
+ uint16_t svwcacth;
+ uint16_t svwbdly;
+ uint8_t svsdtime;
+ uint8_t res5;
+ uint16_t firmval;
+ uint16_t firmbln;
+ uint32_t firmblk;
+ uint32_t fstrsvrb;
+ uint16_t svBlockStorageTid;
+ uint16_t svtid;
+ uint8_t svseccfl;
+ uint8_t res6;
+ uint8_t svhbanum;
+ uint8_t resver;
+ uint32_t drivemagic;
+ uint8_t reserved[20];
+ uint8_t testnum;
+ uint8_t testflags;
+ uint16_t maxErrorCount;
+ uint32_t count;
+ uint32_t startTime;
+ uint32_t interval;
+ uint8_t tstxt0;
+ uint8_t tstxt1;
+ uint8_t serNum[32];
+ uint8_t res8[102];
+ uint32_t fwTestMagic;
+ uint32_t fwTestSeqNum;
+ uint8_t fwTestRes[8];
+ uint8_t smagic[4];
+ uint32_t raidtbl;
+ uint16_t raidline;
+ uint8_t res9[0xF6];
+};
+
+#define AD_SIGNATURE "DPTM"
+#define AD_MAGIC 0x37FC4D1E
+
+static int probe_adraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct adaptec_metadata *ad;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200)-1) * 0x200;
+ ad = (struct adaptec_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct adaptec_metadata));
+ if (!ad)
+ return -1;
+ if (memcmp(ad->smagic, AD_SIGNATURE, sizeof(AD_SIGNATURE)) != 0)
+ return -1;
+ if (ad->b0idcode != be32_to_cpu(AD_MAGIC))
+ return -1;
+ if (blkid_probe_sprintf_version(pr, "%u", ad->resver) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo adraid_idinfo = {
+ .name = "adaptec_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_adraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/btrfs.c b/shlibs/blkid/src/probers/btrfs.c
new file mode 100644
index 000000000..3205e3d97
--- /dev/null
+++ b/shlibs/blkid/src/probers/btrfs.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct btrfs_super_block {
+ uint8_t csum[32];
+ uint8_t fsid[16];
+ uint64_t bytenr;
+ uint64_t flags;
+ uint8_t magic[8];
+ uint64_t generation;
+ uint64_t root;
+ uint64_t chunk_root;
+ uint64_t log_root;
+ uint64_t log_root_transid;
+ uint64_t total_bytes;
+ uint64_t bytes_used;
+ uint64_t root_dir_objectid;
+ uint64_t num_devices;
+ uint32_t sectorsize;
+ uint32_t nodesize;
+ uint32_t leafsize;
+ uint32_t stripesize;
+ uint32_t sys_chunk_array_size;
+ uint64_t chunk_root_generation;
+ uint64_t compat_flags;
+ uint64_t compat_ro_flags;
+ uint64_t incompat_flags;
+ uint16_t csum_type;
+ uint8_t root_level;
+ uint8_t chunk_root_level;
+ uint8_t log_root_level;
+ struct btrfs_dev_item {
+ uint64_t devid;
+ uint64_t total_bytes;
+ uint64_t bytes_used;
+ uint32_t io_align;
+ uint32_t io_width;
+ uint32_t sector_size;
+ uint64_t type;
+ uint64_t generation;
+ uint64_t start_offset;
+ uint32_t dev_group;
+ uint8_t seek_speed;
+ uint8_t bandwidth;
+ uint8_t uuid[16];
+ uint8_t fsid[16];
+ } __attribute__ ((__packed__)) dev_item;
+ uint8_t label[256];
+} __attribute__ ((__packed__));
+
+static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct btrfs_super_block *bfs;
+
+ bfs = blkid_probe_get_sb(pr, mag, struct btrfs_super_block);
+ if (!bfs)
+ return -1;
+
+ if (*bfs->label)
+ blkid_probe_set_label(pr,
+ (unsigned char *) bfs->label,
+ sizeof(bfs->label));
+
+ blkid_probe_set_uuid(pr, bfs->fsid);
+ blkid_probe_set_uuid_as(pr, bfs->dev_item.uuid, "UUID_SUB");
+
+ return 0;
+}
+
+const struct blkid_idinfo btrfs_idinfo =
+{
+ .name = "btrfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_btrfs,
+ .magics =
+ {
+ { .magic = "_BHRfS_M", .len = 8, .kboff = 64, .sboff = 0x40 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/cramfs.c b/shlibs/blkid/src/probers/cramfs.c
new file mode 100644
index 000000000..0ea124b30
--- /dev/null
+++ b/shlibs/blkid/src/probers/cramfs.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct cramfs_super
+{
+ uint8_t magic[4];
+ uint32_t size;
+ uint32_t flags;
+ uint32_t future;
+ uint8_t signature[16];
+ struct cramfs_info
+ {
+ uint32_t crc;
+ uint32_t edition;
+ uint32_t blocks;
+ uint32_t files;
+ } info;
+ uint8_t name[16];
+};
+
+static int probe_cramfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct cramfs_super *cs;
+
+ cs = blkid_probe_get_sb(pr, mag, struct cramfs_super);
+ if (!cs)
+ return -1;
+
+ blkid_probe_set_label(pr, cs->name, sizeof(cs->name));
+ return 0;
+}
+
+const struct blkid_idinfo cramfs_idinfo =
+{
+ .name = "cramfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_cramfs,
+ .magics =
+ {
+ { "\x45\x3d\xcd\x28", 4, 0, 0 },
+ { "\x28\xcd\x3d\x45", 4, 0, 0 },
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/ddf_raid.c b/shlibs/blkid/src/probers/ddf_raid.c
new file mode 100644
index 000000000..41d6e1235
--- /dev/null
+++ b/shlibs/blkid/src/probers/ddf_raid.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+/* http://www.snia.org/standards/home */
+#define DDF_GUID_LENGTH 24
+#define DDF_REV_LENGTH 8
+
+struct ddf_header {
+ uint8_t signature[4];
+ uint32_t crc;
+ uint8_t guid[DDF_GUID_LENGTH];
+ uint8_t ddf_rev[DDF_REV_LENGTH];
+} __attribute__((packed));
+
+static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ int hdrs[] = { 1, 257 };
+ int i;
+ struct ddf_header *ddf = NULL;
+ char version[DDF_REV_LENGTH + 1];
+
+ if (pr->size < 0x30000)
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(hdrs); i++) {
+ uint64_t off = ((pr->size / 0x200) - hdrs[i]) * 0x200;
+
+ ddf = (struct ddf_header *) blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct ddf_header));
+ if (!ddf)
+ return -1;
+
+ if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0 ||
+ memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0)
+ break;
+ ddf = NULL;
+ }
+
+ if (!ddf)
+ return -1;
+
+ blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid));
+
+ memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev));
+ *(version + sizeof(ddf->ddf_rev)) = '\0';
+
+ if (blkid_probe_set_version(pr, version) != 0)
+ return -1;
+ return 0;
+}
+
+const struct blkid_idinfo ddfraid_idinfo = {
+ .name = "ddf_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_ddf,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/ext.c b/shlibs/blkid/src/probers/ext.c
new file mode 100644
index 000000000..671e556c0
--- /dev/null
+++ b/shlibs/blkid/src/probers/ext.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 1999, 2001 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+#include <time.h>
+
+#include "linux_version.h"
+#include "blkidP.h"
+
+struct ext2_super_block {
+ uint32_t s_inodes_count;
+ uint32_t s_blocks_count;
+ uint32_t s_r_blocks_count;
+ uint32_t s_free_blocks_count;
+ uint32_t s_free_inodes_count;
+ uint32_t s_first_data_block;
+ uint32_t s_log_block_size;
+ uint32_t s_dummy3[7];
+ unsigned char s_magic[2];
+ uint16_t s_state;
+ uint16_t s_errors;
+ uint16_t s_minor_rev_level;
+ uint32_t s_lastcheck;
+ uint32_t s_checkinterval;
+ uint32_t s_creator_os;
+ uint32_t s_rev_level;
+ uint16_t s_def_resuid;
+ uint16_t s_def_resgid;
+ uint32_t s_first_ino;
+ uint16_t s_inode_size;
+ uint16_t s_block_group_nr;
+ uint32_t s_feature_compat;
+ uint32_t s_feature_incompat;
+ uint32_t s_feature_ro_compat;
+ unsigned char s_uuid[16];
+ char s_volume_name[16];
+ char s_last_mounted[64];
+ uint32_t s_algorithm_usage_bitmap;
+ uint8_t s_prealloc_blocks;
+ uint8_t s_prealloc_dir_blocks;
+ uint16_t s_reserved_gdt_blocks;
+ uint8_t s_journal_uuid[16];
+ uint32_t s_journal_inum;
+ uint32_t s_journal_dev;
+ uint32_t s_last_orphan;
+ uint32_t s_hash_seed[4];
+ uint8_t s_def_hash_version;
+ uint8_t s_jnl_backup_type;
+ uint16_t s_reserved_word_pad;
+ uint32_t s_default_mount_opts;
+ uint32_t s_first_meta_bg;
+ uint32_t s_mkfs_time;
+ uint32_t s_jnl_blocks[17];
+ uint32_t s_blocks_count_hi;
+ uint32_t s_r_blocks_count_hi;
+ uint32_t s_free_blocks_hi;
+ uint16_t s_min_extra_isize;
+ uint16_t s_want_extra_isize;
+ uint32_t s_flags;
+ uint16_t s_raid_stride;
+ uint16_t s_mmp_interval;
+ uint64_t s_mmp_block;
+ uint32_t s_raid_stripe_width;
+ uint32_t s_reserved[163];
+};
+
+/* magic string */
+#define EXT_SB_MAGIC "\123\357"
+/* supper block offset */
+#define EXT_SB_OFF 0x400
+/* supper block offset in kB */
+#define EXT_SB_KBOFF (EXT_SB_OFF >> 10)
+/* magic string offset within super block */
+#define EXT_MAG_OFF 0x38
+
+
+
+/* for s_flags */
+#define EXT2_FLAGS_TEST_FILESYS 0x0004
+
+/* for s_feature_compat */
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+
+/* for s_feature_ro_compat */
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
+
+/* for s_feature_incompat */
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
+#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
+
+#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+ EXT2_FEATURE_INCOMPAT_META_BG)
+#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP
+#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP
+
+#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+ EXT3_FEATURE_INCOMPAT_RECOVER| \
+ EXT2_FEATURE_INCOMPAT_META_BG)
+#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~EXT3_FEATURE_INCOMPAT_SUPP
+#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP
+
+
+#ifdef FUCK
+
+/* for s_flags */
+#define EXT2_FLAGS_TEST_FILESYS 0x0004
+
+/* for s_feature_compat */
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+
+/* for s_feature_ro_compat */
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
+
+/* for s_feature_incompat */
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
+#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
+
+#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+ EXT2_FEATURE_INCOMPAT_META_BG)
+#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP
+#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP
+
+#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
+ EXT3_FEATURE_INCOMPAT_RECOVER| \
+ EXT2_FEATURE_INCOMPAT_META_BG)
+#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED (~EXT3_FEATURE_INCOMPAT_SUPP)
+#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT3_FEATURE_RO_COMPAT_SUPP)
+
+#endif
+
+/*
+ * Check to see if a filesystem is in /proc/filesystems.
+ * Returns 1 if found, 0 if not
+ */
+static int fs_proc_check(const char *fs_name)
+{
+ FILE *f;
+ char buf[80], *cp, *t;
+
+ f = fopen("/proc/filesystems", "r");
+ if (!f)
+ return 0;
+ while (!feof(f)) {
+ if (!fgets(buf, sizeof(buf), f))
+ break;
+ cp = buf;
+ if (!isspace(*cp)) {
+ while (*cp && !isspace(*cp))
+ cp++;
+ }
+ while (*cp && isspace(*cp))
+ cp++;
+ if ((t = strchr(cp, '\n')) != NULL)
+ *t = 0;
+ if ((t = strchr(cp, '\t')) != NULL)
+ *t = 0;
+ if ((t = strchr(cp, ' ')) != NULL)
+ *t = 0;
+ if (!strcmp(fs_name, cp)) {
+ fclose(f);
+ return 1;
+ }
+ }
+ fclose(f);
+ return (0);
+}
+
+/*
+ * Check to see if a filesystem is available as a module
+ * Returns 1 if found, 0 if not
+ */
+static int check_for_modules(const char *fs_name)
+{
+#ifdef __linux__
+ struct utsname uts;
+ FILE *f;
+ char buf[1024], *cp, *t;
+ int i;
+
+ if (uname(&uts))
+ return 0;
+ snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release);
+
+ f = fopen(buf, "r");
+ if (!f)
+ return 0;
+ while (!feof(f)) {
+ if (!fgets(buf, sizeof(buf), f))
+ break;
+ if ((cp = strchr(buf, ':')) != NULL)
+ *cp = 0;
+ else
+ continue;
+ if ((cp = strrchr(buf, '/')) == NULL)
+ continue;
+ cp++;
+ i = strlen(cp);
+ if (i > 3) {
+ t = cp + i - 3;
+ if (!strcmp(t, ".ko"))
+ *t = 0;
+ }
+ if (!strcmp(cp, fs_name)) {
+ fclose(f);
+ return 1;
+ }
+ }
+ fclose(f);
+#endif /* __linux__ */
+ return 0;
+}
+
+/*
+ * Starting in 2.6.29, ext4 can be used to support filesystems
+ * without a journal.
+ */
+#define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29)
+
+static int system_supports_ext2(void)
+{
+ static time_t last_check = 0;
+ static int ret = -1;
+ time_t now = time(0);
+
+ if (ret != -1 || (now - last_check) < 5)
+ return ret;
+ last_check = now;
+ ret = (fs_proc_check("ext2") || check_for_modules("ext2"));
+ return ret;
+}
+
+static int system_supports_ext4(void)
+{
+ static time_t last_check = 0;
+ static int ret = -1;
+ time_t now = time(0);
+
+ if (ret != -1 || (now - last_check) < 5)
+ return ret;
+ last_check = now;
+ ret = (fs_proc_check("ext4") || check_for_modules("ext4"));
+ return ret;
+}
+
+static int system_supports_ext4dev(void)
+{
+ static time_t last_check = 0;
+ static int ret = -1;
+ time_t now = time(0);
+
+ if (ret != -1 || (now - last_check) < 5)
+ return ret;
+ last_check = now;
+ ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev"));
+ return ret;
+}
+/*
+ * reads superblock and returns:
+ * fc = feature_compat
+ * fi = feature_incompat
+ * frc = feature_ro_compat
+ */
+static struct ext2_super_block *ext_get_super(
+ blkid_probe pr, uint32_t *fc, uint32_t *fi, uint32_t *frc)
+{
+ struct ext2_super_block *es;
+
+ es = (struct ext2_super_block *)
+ blkid_probe_get_buffer(pr, EXT_SB_OFF, 0x200);
+ if (!es)
+ return NULL;
+ if (fc)
+ *fc = le32_to_cpu(es->s_feature_compat);
+ if (fi)
+ *fi = le32_to_cpu(es->s_feature_incompat);
+ if (frc)
+ *frc = le32_to_cpu(es->s_feature_ro_compat);
+
+ return es;
+}
+
+static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es)
+{
+ DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n",
+ le32_to_cpu(es->s_feature_compat),
+ le32_to_cpu(es->s_feature_incompat),
+ le32_to_cpu(es->s_feature_ro_compat)));
+
+ if (strlen(es->s_volume_name))
+ blkid_probe_set_label(pr, (unsigned char *) es->s_volume_name,
+ sizeof(es->s_volume_name));
+ blkid_probe_set_uuid(pr, es->s_uuid);
+
+ if (le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL)
+ blkid_probe_set_uuid_as(pr, es->s_journal_uuid, "EXT_JOURNAL");
+
+ if (ver != 2 && (pr->probreq & BLKID_PROBREQ_SECTYPE) &&
+ ((le32_to_cpu(es->s_feature_incompat) & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0))
+ blkid_probe_set_value(pr, "SEC_TYPE",
+ (unsigned char *) "ext2",
+ sizeof("ext2"));
+
+ blkid_probe_sprintf_version(pr, "%u.%u",
+ le32_to_cpu(es->s_rev_level),
+ le16_to_cpu(es->s_minor_rev_level));
+}
+
+
+static int probe_jbd(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ext2_super_block *es;
+ uint32_t fi;
+
+ es = ext_get_super(pr, NULL, &fi, NULL);
+ if (!es)
+ return -BLKID_ERR_PARAM;
+ if (!(fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
+ return -BLKID_ERR_PARAM;
+
+ ext_get_info(pr, 2, es);
+ return 0;
+}
+
+static int probe_ext2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ext2_super_block *es;
+ uint32_t fc, frc, fi;
+
+ es = ext_get_super(pr, &fc, &fi, &frc);
+ if (!es)
+ return -BLKID_ERR_PARAM;
+
+ /* Distinguish between ext3 and ext2 */
+ if (fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL)
+ return -BLKID_ERR_PARAM;
+
+ /* Any features which ext2 doesn't understand */
+ if ((frc & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) ||
+ (fi & EXT2_FEATURE_INCOMPAT_UNSUPPORTED))
+ return -BLKID_ERR_PARAM;
+
+ /*
+ * If ext2 is not present, but ext4 or ext4dev are, then
+ * disclaim we are ext2
+ */
+ if (!system_supports_ext2() &&
+ (system_supports_ext4() || system_supports_ext4dev()) &&
+ get_linux_version() >= EXT4_SUPPORTS_EXT2)
+ return -BLKID_ERR_PARAM;
+
+ ext_get_info(pr, 2, es);
+ return 0;
+}
+
+static int probe_ext3(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ext2_super_block *es;
+ uint32_t fc, frc, fi;
+
+ es = ext_get_super(pr, &fc, &fi, &frc);
+ if (!es)
+ return -BLKID_ERR_PARAM;
+
+ /* ext3 requires journal */
+ if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+ return -BLKID_ERR_PARAM;
+
+ /* Any features which ext3 doesn't understand */
+ if ((frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) ||
+ (fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
+ return -BLKID_ERR_PARAM;
+
+ ext_get_info(pr, 3, es);
+ return 0;
+}
+
+
+static int probe_ext4dev(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ext2_super_block *es;
+ uint32_t fc, frc, fi;
+
+ es = ext_get_super(pr, &fc, &fi, &frc);
+ if (!es)
+ return -BLKID_ERR_PARAM;
+
+ /* Distinguish from jbd */
+ if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
+ return -BLKID_ERR_PARAM;
+
+ /*
+ * If the filesystem does not have a journal and ext2 and ext4
+ * is not present, then force this to be detected as an
+ * ext4dev filesystem.
+ */
+ if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+ !system_supports_ext2() && !system_supports_ext4() &&
+ system_supports_ext4dev() &&
+ get_linux_version() >= EXT4_SUPPORTS_EXT2)
+ goto force_ext4dev;
+
+ /*
+ * If the filesystem is marked as OK for use by in-development
+ * filesystem code, but ext4dev is not supported, and ext4 is,
+ * then don't call ourselves ext4dev, since we should be
+ * detected as ext4 in that case.
+ *
+ * If the filesystem is marked as in use by production
+ * filesystem, then it can only be used by ext4 and NOT by
+ * ext4dev, so always disclaim we are ext4dev in that case.
+ */
+ if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) {
+ if (!system_supports_ext4dev() && system_supports_ext4())
+ return -BLKID_ERR_PARAM;
+ } else
+ return -BLKID_ERR_PARAM;
+
+force_ext4dev:
+ ext_get_info(pr, 4, es);
+ return 0;
+}
+
+static int probe_ext4(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ext2_super_block *es;
+ uint32_t fc, frc, fi;
+
+ es = ext_get_super(pr, &fc, &fi, &frc);
+ if (!es)
+ return -1;
+
+ /* Distinguish from jbd */
+ if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
+ return -BLKID_ERR_PARAM;
+
+ /* Ext4 has at least one feature which ext3 doesn't understand */
+ if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) &&
+ !(fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
+ return -BLKID_ERR_PARAM;
+
+ /*
+ * If the filesystem does not have a journal and ext2 is not
+ * present, then force this to be detected as an ext2
+ * filesystem.
+ */
+ if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+ !system_supports_ext2() && system_supports_ext4() &&
+ get_linux_version() >= EXT4_SUPPORTS_EXT2)
+ goto force_ext4;
+
+ /*
+ * If the filesystem is a OK for use by in-development
+ * filesystem code, and ext4dev is supported or ext4 is not
+ * supported, then don't call ourselves ext4, so we can redo
+ * the detection and mark the filesystem as ext4dev.
+ *
+ * If the filesystem is marked as in use by production
+ * filesystem, then it can only be used by ext4 and NOT by
+ * ext4dev.
+ */
+ if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) {
+ if (system_supports_ext4dev() || !system_supports_ext4())
+ return -BLKID_ERR_PARAM;
+ }
+
+force_ext4:
+ ext_get_info(pr, 4, es);
+ return 0;
+}
+
+#define BLKID_EXT_MAGICS \
+ { \
+ { \
+ .magic = EXT_SB_MAGIC, \
+ .len = sizeof(EXT_SB_MAGIC) - 1, \
+ .kboff = EXT_SB_KBOFF, \
+ .sboff = EXT_MAG_OFF \
+ }, \
+ { NULL } \
+ }
+
+const struct blkid_idinfo jbd_idinfo =
+{
+ .name = "jbd",
+ .usage = BLKID_USAGE_OTHER,
+ .probefunc = probe_jbd,
+ .magics = BLKID_EXT_MAGICS
+};
+
+const struct blkid_idinfo ext2_idinfo =
+{
+ .name = "ext2",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ext2,
+ .magics = BLKID_EXT_MAGICS
+};
+
+const struct blkid_idinfo ext3_idinfo =
+{
+ .name = "ext3",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ext3,
+ .magics = BLKID_EXT_MAGICS
+};
+
+const struct blkid_idinfo ext4_idinfo =
+{
+ .name = "ext4",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ext4,
+ .magics = BLKID_EXT_MAGICS
+};
+
+const struct blkid_idinfo ext4dev_idinfo =
+{
+ .name = "ext4dev",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ext4dev,
+ .magics = BLKID_EXT_MAGICS
+};
+
diff --git a/shlibs/blkid/src/probers/gfs.c b/shlibs/blkid/src/probers/gfs.c
new file mode 100644
index 000000000..584561cf3
--- /dev/null
+++ b/shlibs/blkid/src/probers/gfs.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+/* Common gfs/gfs2 constants: */
+#define GFS_LOCKNAME_LEN 64
+
+/* gfs1 constants: */
+#define GFS_FORMAT_FS 1309
+#define GFS_FORMAT_MULTI 1401
+/* gfs2 constants: */
+#define GFS2_FORMAT_FS 1801
+#define GFS2_FORMAT_MULTI 1900
+
+struct gfs2_meta_header {
+ uint32_t mh_magic;
+ uint32_t mh_type;
+ uint64_t __pad0; /* Was generation number in gfs1 */
+ uint32_t mh_format;
+ uint32_t __pad1; /* Was incarnation number in gfs1 */
+};
+
+struct gfs2_inum {
+ uint64_t no_formal_ino;
+ uint64_t no_addr;
+};
+
+struct gfs2_sb {
+ struct gfs2_meta_header sb_header;
+
+ uint32_t sb_fs_format;
+ uint32_t sb_multihost_format;
+ uint32_t __pad0; /* Was superblock flags in gfs1 */
+
+ uint32_t sb_bsize;
+ uint32_t sb_bsize_shift;
+ uint32_t __pad1; /* Was journal segment size in gfs1 */
+
+ struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */
+ struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */
+ struct gfs2_inum sb_root_dir;
+
+ char sb_lockproto[GFS_LOCKNAME_LEN];
+ char sb_locktable[GFS_LOCKNAME_LEN];
+
+ struct gfs2_inum __pad3; /* Was quota inode in gfs1 */
+ struct gfs2_inum __pad4; /* Was licence inode in gfs1 */
+ uint8_t sb_uuid[16]; /* The UUID maybe 0 for backwards compat */
+};
+
+static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct gfs2_sb *sbd;
+
+ sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
+ if (!sbd)
+ return -1;
+
+ if (be32_to_cpu(sbd->sb_fs_format) == GFS_FORMAT_FS &&
+ be32_to_cpu(sbd->sb_multihost_format) == GFS_FORMAT_MULTI)
+ {
+ if (*sbd->sb_locktable)
+ blkid_probe_set_label(pr,
+ (unsigned char *) sbd->sb_locktable,
+ sizeof(sbd->sb_locktable));
+
+ blkid_probe_set_uuid(pr, sbd->sb_uuid);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct gfs2_sb *sbd;
+
+ sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
+ if (!sbd)
+ return -1;
+
+ if (be32_to_cpu(sbd->sb_fs_format) == GFS2_FORMAT_FS &&
+ be32_to_cpu(sbd->sb_multihost_format) == GFS2_FORMAT_MULTI)
+ {
+ if (*sbd->sb_locktable)
+ blkid_probe_set_label(pr,
+ (unsigned char *) sbd->sb_locktable,
+ sizeof(sbd->sb_locktable));
+ blkid_probe_set_uuid(pr, sbd->sb_uuid);
+ blkid_probe_set_version(pr, "1");
+ return 0;
+ }
+ return -1;
+}
+
+const struct blkid_idinfo gfs_idinfo =
+{
+ .name = "gfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_gfs,
+ .magics =
+ {
+ { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo gfs2_idinfo =
+{
+ .name = "gfs2",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_gfs2,
+ .magics =
+ {
+ { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/hfs.c b/shlibs/blkid/src/probers/hfs.c
new file mode 100644
index 000000000..4cdef0ee7
--- /dev/null
+++ b/shlibs/blkid/src/probers/hfs.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "blkidP.h"
+#include "md5.h"
+
+/* HFS / HFS+ */
+struct hfs_finder_info {
+ uint32_t boot_folder;
+ uint32_t start_app;
+ uint32_t open_folder;
+ uint32_t os9_folder;
+ uint32_t reserved;
+ uint32_t osx_folder;
+ uint8_t id[8];
+} __attribute__((packed));
+
+struct hfs_mdb {
+ uint8_t signature[2];
+ uint32_t cr_date;
+ uint32_t ls_Mod;
+ uint16_t atrb;
+ uint16_t nm_fls;
+ uint16_t vbm_st;
+ uint16_t alloc_ptr;
+ uint16_t nm_al_blks;
+ uint32_t al_blk_size;
+ uint32_t clp_size;
+ uint16_t al_bl_st;
+ uint32_t nxt_cnid;
+ uint16_t free_bks;
+ uint8_t label_len;
+ uint8_t label[27];
+ uint32_t vol_bkup;
+ uint16_t vol_seq_num;
+ uint32_t wr_cnt;
+ uint32_t xt_clump_size;
+ uint32_t ct_clump_size;
+ uint16_t num_root_dirs;
+ uint32_t file_count;
+ uint32_t dir_count;
+ struct hfs_finder_info finder_info;
+ uint8_t embed_sig[2];
+ uint16_t embed_startblock;
+ uint16_t embed_blockcount;
+} __attribute__((packed));
+
+
+#define HFS_NODE_LEAF 0xff
+#define HFSPLUS_POR_CNID 1
+
+struct hfsplus_bnode_descriptor {
+ uint32_t next;
+ uint32_t prev;
+ uint8_t type;
+ uint8_t height;
+ uint16_t num_recs;
+ uint16_t reserved;
+} __attribute__((packed));
+
+struct hfsplus_bheader_record {
+ uint16_t depth;
+ uint32_t root;
+ uint32_t leaf_count;
+ uint32_t leaf_head;
+ uint32_t leaf_tail;
+ uint16_t node_size;
+} __attribute__((packed));
+
+struct hfsplus_catalog_key {
+ uint16_t key_len;
+ uint32_t parent_id;
+ uint16_t unicode_len;
+ uint8_t unicode[255 * 2];
+} __attribute__((packed));
+
+struct hfsplus_extent {
+ uint32_t start_block;
+ uint32_t block_count;
+} __attribute__((packed));
+
+#define HFSPLUS_EXTENT_COUNT 8
+struct hfsplus_fork {
+ uint64_t total_size;
+ uint32_t clump_size;
+ uint32_t total_blocks;
+ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
+} __attribute__((packed));
+
+struct hfsplus_vol_header {
+ uint8_t signature[2];
+ uint16_t version;
+ uint32_t attributes;
+ uint32_t last_mount_vers;
+ uint32_t reserved;
+ uint32_t create_date;
+ uint32_t modify_date;
+ uint32_t backup_date;
+ uint32_t checked_date;
+ uint32_t file_count;
+ uint32_t folder_count;
+ uint32_t blocksize;
+ uint32_t total_blocks;
+ uint32_t free_blocks;
+ uint32_t next_alloc;
+ uint32_t rsrc_clump_sz;
+ uint32_t data_clump_sz;
+ uint32_t next_cnid;
+ uint32_t write_count;
+ uint64_t encodings_bmp;
+ struct hfs_finder_info finder_info;
+ struct hfsplus_fork alloc_file;
+ struct hfsplus_fork ext_file;
+ struct hfsplus_fork cat_file;
+ struct hfsplus_fork attr_file;
+ struct hfsplus_fork start_file;
+} __attribute__((packed));
+
+static int hfs_set_uuid(blkid_probe pr, unsigned char const *hfs_info, size_t len)
+{
+ static unsigned char const hash_init[16] = {
+ 0xb3, 0xe2, 0x0f, 0x39, 0xf2, 0x92, 0x11, 0xd6,
+ 0x97, 0xa4, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
+ };
+ unsigned char uuid[16];
+ struct MD5Context md5c;
+
+ if (memcmp(hfs_info, "\0\0\0\0\0\0\0\0", len) == 0)
+ return -1;
+ MD5Init(&md5c);
+ MD5Update(&md5c, hash_init, 16);
+ MD5Update(&md5c, hfs_info, len);
+ MD5Final(uuid, &md5c);
+ uuid[6] = 0x30 | (uuid[6] & 0x0f);
+ uuid[8] = 0x80 | (uuid[8] & 0x3f);
+ return blkid_probe_set_uuid(pr, uuid);
+}
+
+static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct hfs_mdb *hfs;
+
+ hfs = blkid_probe_get_sb(pr, mag, struct hfs_mdb);
+ if (!hfs)
+ return -1;
+
+ if ((memcmp(hfs->embed_sig, "H+", 2) == 0) ||
+ (memcmp(hfs->embed_sig, "HX", 2) == 0))
+ return 1; /* Not hfs, but an embedded HFS+ */
+
+ hfs_set_uuid(pr, hfs->finder_info.id, sizeof(hfs->finder_info.id));
+
+ blkid_probe_set_label(pr, hfs->label, hfs->label_len);
+ return 0;
+}
+
+static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
+ struct hfsplus_bnode_descriptor *descr;
+ struct hfsplus_bheader_record *bnode;
+ struct hfsplus_catalog_key *key;
+ struct hfsplus_vol_header *hfsplus;
+ struct hfs_mdb *sbd;
+ unsigned int alloc_block_size;
+ unsigned int alloc_first_block;
+ unsigned int embed_first_block;
+ unsigned int off = 0;
+ unsigned int blocksize;
+ unsigned int cat_block;
+ unsigned int ext_block_start;
+ unsigned int ext_block_count;
+ unsigned int record_count;
+ unsigned int leaf_node_head;
+ unsigned int leaf_node_count;
+ unsigned int leaf_node_size;
+ unsigned int leaf_block;
+ int ext;
+ uint64_t leaf_off;
+ unsigned char *buf;
+
+ sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb);
+ if (!sbd)
+ return -1;
+
+ /* Check for a HFS+ volume embedded in a HFS volume */
+ if (memcmp(sbd->signature, "BD", 2) == 0) {
+ if ((memcmp(sbd->embed_sig, "H+", 2) != 0) &&
+ (memcmp(sbd->embed_sig, "HX", 2) != 0))
+ /* This must be an HFS volume, so fail */
+ return 1;
+
+ alloc_block_size = be32_to_cpu(sbd->al_blk_size);
+ alloc_first_block = be16_to_cpu(sbd->al_bl_st);
+ embed_first_block = be16_to_cpu(sbd->embed_startblock);
+ off = (alloc_first_block * 512) +
+ (embed_first_block * alloc_block_size);
+
+ buf = blkid_probe_get_buffer(pr,
+ off + (mag->kboff * 1024),
+ sizeof(struct hfsplus_vol_header));
+ hfsplus = (struct hfsplus_vol_header *) buf;
+
+ } else
+ hfsplus = blkid_probe_get_sb(pr, mag,
+ struct hfsplus_vol_header);
+
+ if (!hfsplus)
+ return -1;
+
+ if ((memcmp(hfsplus->signature, "H+", 2) != 0) &&
+ (memcmp(hfsplus->signature, "HX", 2) != 0))
+ return 1;
+
+ hfs_set_uuid(pr, hfsplus->finder_info.id, sizeof(hfsplus->finder_info.id));
+
+ blocksize = be32_to_cpu(hfsplus->blocksize);
+ memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
+ cat_block = be32_to_cpu(extents[0].start_block);
+
+ buf = blkid_probe_get_buffer(pr,
+ off + (cat_block * blocksize), 0x2000);
+ if (!buf)
+ return 0;
+
+ bnode = (struct hfsplus_bheader_record *)
+ &buf[sizeof(struct hfsplus_bnode_descriptor)];
+
+ leaf_node_head = be32_to_cpu(bnode->leaf_head);
+ leaf_node_size = be16_to_cpu(bnode->node_size);
+ leaf_node_count = be32_to_cpu(bnode->leaf_count);
+ if (leaf_node_count == 0)
+ return 0;
+
+ leaf_block = (leaf_node_head * leaf_node_size) / blocksize;
+
+ /* get physical location */
+ for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) {
+ ext_block_start = be32_to_cpu(extents[ext].start_block);
+ ext_block_count = be32_to_cpu(extents[ext].block_count);
+ if (ext_block_count == 0)
+ return 0;
+
+ /* this is our extent */
+ if (leaf_block < ext_block_count)
+ break;
+
+ leaf_block -= ext_block_count;
+ }
+ if (ext == HFSPLUS_EXTENT_COUNT)
+ return 0;
+
+ leaf_off = (ext_block_start + leaf_block) * blocksize;
+
+ buf = blkid_probe_get_buffer(pr, off + leaf_off, leaf_node_size);
+ if (!buf)
+ return 0;
+
+ descr = (struct hfsplus_bnode_descriptor *) buf;
+ record_count = be16_to_cpu(descr->num_recs);
+ if (record_count == 0)
+ return 0;
+
+ if (descr->type != HFS_NODE_LEAF)
+ return 0;
+
+ key = (struct hfsplus_catalog_key *)
+ &buf[sizeof(struct hfsplus_bnode_descriptor)];
+
+ if (be32_to_cpu(key->parent_id) != HFSPLUS_POR_CNID)
+ return 0;
+
+ blkid_probe_set_utf8label(pr, key->unicode,
+ be16_to_cpu(key->unicode_len) * 2,
+ BLKID_ENC_UTF16BE);
+ return 0;
+}
+
+const struct blkid_idinfo hfs_idinfo =
+{
+ .name = "hfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_hfs,
+ .magics =
+ {
+ { .magic = "BD", .len = 2, .kboff = 1 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo hfsplus_idinfo =
+{
+ .name = "hfsplus",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_hfsplus,
+ .magics =
+ {
+ { .magic = "BD", .len = 2, .kboff = 1 },
+ { .magic = "H+", .len = 2, .kboff = 1 },
+ { .magic = "HX", .len = 2, .kboff = 1 },
+ { NULL }
+ }
+};
diff --git a/shlibs/blkid/src/probers/highpoint_raid.c b/shlibs/blkid/src/probers/highpoint_raid.c
new file mode 100644
index 000000000..c7c92db44
--- /dev/null
+++ b/shlibs/blkid/src/probers/highpoint_raid.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct hpt45x_metadata {
+ uint32_t magic;
+};
+
+#define HPT45X_MAGIC_OK 0x5a7816f3
+#define HPT45X_MAGIC_BAD 0x5a7816fd
+
+static int probe_highpoint45x(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct hpt45x_metadata *hpt;
+ uint64_t off;
+ uint32_t magic;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 11) * 0x200;
+ hpt = (struct hpt45x_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct hpt45x_metadata));
+ if (!hpt)
+ return -1;
+ magic = le32_to_cpu(hpt->magic);
+ if (magic != HPT45X_MAGIC_OK && magic != HPT45X_MAGIC_BAD)
+ return -1;
+ return 0;
+}
+
+const struct blkid_idinfo highpoint45x_idinfo = {
+ .name = "highpoint_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_highpoint45x,
+ .magics = BLKID_NONE_MAGIC
+};
+
+const struct blkid_idinfo highpoint37x_idinfo = {
+ .name = "highpoint_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .magics = {
+ { .magic = "\xf0\x16\x78\x5a", .len = 4, .kboff = 4 },
+ { .magic = "\xfd\x16\x78\x5a", .len = 4, .kboff = 4 },
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/hpfs.c b/shlibs/blkid/src/probers/hpfs.c
new file mode 100644
index 000000000..2f5f0d198
--- /dev/null
+++ b/shlibs/blkid/src/probers/hpfs.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct hpfs_boot_block
+{
+ uint8_t jmp[3];
+ uint8_t oem_id[8];
+ uint8_t bytes_per_sector[2];
+ uint8_t sectors_per_cluster;
+ uint8_t n_reserved_sectors[2];
+ uint8_t n_fats;
+ uint8_t n_rootdir_entries[2];
+ uint8_t n_sectors_s[2];
+ uint8_t media_byte;
+ uint16_t sectors_per_fat;
+ uint16_t sectors_per_track;
+ uint16_t heads_per_cyl;
+ uint32_t n_hidden_sectors;
+ uint32_t n_sectors_l;
+ uint8_t drive_number;
+ uint8_t mbz;
+ uint8_t sig_28h;
+ uint8_t vol_serno[4];
+ uint8_t vol_label[11];
+ uint8_t sig_hpfs[8];
+ uint8_t pad[448];
+ uint8_t magic[2];
+};
+
+struct hpfs_super_block
+{
+ uint8_t magic[4];
+ uint8_t magic1[4];
+ uint8_t version;
+};
+
+struct hpfs_spare_super
+{
+ uint8_t magic[4];
+ uint8_t magic1[4];
+};
+
+
+#define HPFS_SB_OFFSET 0x2000
+#define HPFS_SBSPARE_OFFSET 0x2200
+
+static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct hpfs_super_block *hs;
+ struct hpfs_spare_super *hss;
+ struct hpfs_boot_block *hbb;
+ uint8_t version;
+
+ /* super block */
+ hs = blkid_probe_get_sb(pr, mag, struct hpfs_super_block);
+ if (!hs)
+ return -1;
+ version = hs->version;
+
+ /* spare super block */
+ hss = (struct hpfs_spare_super *)
+ blkid_probe_get_buffer(pr,
+ HPFS_SBSPARE_OFFSET,
+ sizeof(struct hpfs_spare_super));
+ if (!hss)
+ return -1;
+ if (memcmp(hss->magic, "\x49\x18\x91\xf9", 4) != 0)
+ return -1;
+
+ /* boot block (with UUID and LABEL) */
+ hbb = (struct hpfs_boot_block *)
+ blkid_probe_get_buffer(pr,
+ 0,
+ sizeof(struct hpfs_boot_block));
+ if (!hbb)
+ return -1;
+ if (memcmp(hbb->magic, "\x55\xaa", 2) == 0 &&
+ memcmp(hbb->sig_hpfs, "HPFS", 4) == 0 &&
+ hbb->sig_28h == 0x28) {
+ blkid_probe_set_label(pr, hbb->vol_label, sizeof(hbb->vol_label));
+ blkid_probe_sprintf_uuid(pr,
+ hbb->vol_serno, sizeof(hbb->vol_serno),
+ "%02X%02X-%02X%02X",
+ hbb->vol_serno[3], hbb->vol_serno[2],
+ hbb->vol_serno[1], hbb->vol_serno[0]);
+ }
+ blkid_probe_sprintf_version(pr, "%u", version);
+
+ return 0;
+}
+
+const struct blkid_idinfo hpfs_idinfo =
+{
+ .name = "hpfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_hpfs,
+ .magics =
+ {
+ {
+ .magic = "\x49\xe8\x95\xf9",
+ .len = 4,
+ .kboff = (HPFS_SB_OFFSET >> 10)
+ },
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/iso9660.c b/shlibs/blkid/src/probers/iso9660.c
new file mode 100644
index 000000000..ca53e3ae4
--- /dev/null
+++ b/shlibs/blkid/src/probers/iso9660.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired also by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct iso_volume_descriptor {
+ unsigned char vd_type;
+ unsigned char vd_id[5];
+ unsigned char vd_version;
+ unsigned char flags;
+ unsigned char system_id[32];
+ unsigned char volume_id[32];
+ unsigned char unused[8];
+ unsigned char space_size[8];
+ unsigned char escape_sequences[8];
+};
+
+#define ISO_SUPERBLOCK_OFFSET 0x8000
+#define ISO_SECTOR_SIZE 0x800
+#define ISO_VD_OFFSET (ISO_SUPERBLOCK_OFFSET + ISO_SECTOR_SIZE)
+#define ISO_VD_SUPPLEMENTARY 0x2
+#define ISO_VD_END 0xff
+#define ISO_VD_MAX 16
+
+struct high_sierra_volume_descriptor {
+ unsigned char foo[8];
+ unsigned char type;
+ unsigned char id[5];
+ unsigned char version;
+ unsigned char unused1;
+ unsigned char system_id[32];
+ unsigned char volume_id[32];
+};
+
+/* old High Sierra format */
+static int probe_iso9660_hsfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct high_sierra_volume_descriptor *iso;
+
+ iso = blkid_probe_get_sb(pr, mag, struct high_sierra_volume_descriptor);
+ if (!iso)
+ return -1;
+
+ blkid_probe_set_version(pr, "High Sierra");
+ blkid_probe_set_label(pr, iso->volume_id, sizeof(iso->volume_id));
+ return 0;
+}
+
+/* iso9660 [+ Microsoft Joliet Extension] */
+static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct iso_volume_descriptor *iso;
+ unsigned char label[32];
+ int i;
+ int off;
+
+ if (strcmp(mag->magic, "CDROM") == 0)
+ return probe_iso9660_hsfs(pr, mag);
+
+ iso = blkid_probe_get_sb(pr, mag, struct iso_volume_descriptor);
+ if (!iso)
+ return -1;
+
+ memcpy(label, iso->volume_id, sizeof(label));
+
+ /* Joliet Extension */
+ off = ISO_VD_OFFSET;
+ for (i = 0; i < ISO_VD_MAX; i++) {
+ uint8_t svd_label[64];
+
+ iso = (struct iso_volume_descriptor *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct iso_volume_descriptor));
+
+ if (iso == NULL || iso->vd_type == ISO_VD_END)
+ break;
+ if (iso->vd_type != ISO_VD_SUPPLEMENTARY)
+ continue;
+
+ if (memcmp(iso->escape_sequences, "%/@", 3) == 0 ||
+ memcmp(iso->escape_sequences, "%/C", 3) == 0 ||
+ memcmp(iso->escape_sequences, "%/E", 3) == 0) {
+
+ blkid_probe_set_utf8label(pr,
+ iso->volume_id,
+ sizeof(svd_label),
+ BLKID_ENC_UTF16BE);
+
+ blkid_probe_set_version(pr, "Joliet Extension");
+ goto has_label;
+ }
+ off += ISO_SECTOR_SIZE;
+ }
+
+ /* Joliet not found, let use standard iso label */
+ blkid_probe_set_label(pr, label, sizeof(label));
+
+has_label:
+ return 0;
+}
+
+
+const struct blkid_idinfo iso9660_idinfo =
+{
+ .name = "iso9660",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_iso9660,
+ .flags = BLKID_IDINFO_TOLERANT,
+ .magics =
+ {
+ { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "CDROM", .len = 5, .kboff = 32, .sboff = 9 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/isw_raid.c b/shlibs/blkid/src/probers/isw_raid.c
new file mode 100644
index 000000000..f9ae7453f
--- /dev/null
+++ b/shlibs/blkid/src/probers/isw_raid.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct isw_metadata {
+ uint8_t sig[32];
+ uint32_t check_sum;
+ uint32_t mpb_size;
+ uint32_t family_num;
+ uint32_t generation_num;
+};
+
+#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. "
+
+
+static int probe_iswraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct isw_metadata *isw;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 2) * 0x200;
+ isw = (struct isw_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct isw_metadata));
+ if (!isw)
+ return -1;
+ if (memcmp(isw->sig, ISW_SIGNATURE, sizeof(ISW_SIGNATURE)-1) != 0)
+ return -1;
+ if (blkid_probe_sprintf_version(pr, "%6s",
+ &isw->sig[sizeof(ISW_SIGNATURE)-1]) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo iswraid_idinfo = {
+ .name = "isw_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_iswraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/jfs.c b/shlibs/blkid/src/probers/jfs.c
new file mode 100644
index 000000000..5d9b39acd
--- /dev/null
+++ b/shlibs/blkid/src/probers/jfs.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct jfs_super_block {
+ unsigned char js_magic[4];
+ uint32_t js_version;
+ uint64_t js_size;
+ uint32_t js_bsize; /* 4: aggregate block size in bytes */
+ uint16_t js_l2bsize; /* 2: log2 of s_bsize */
+ uint16_t js_l2bfactor; /* 2: log2(s_bsize/hardware block size) */
+ uint32_t js_pbsize; /* 4: hardware/LVM block size in bytes */
+ uint16_t js_l2pbsize; /* 2: log2 of s_pbsize */
+ uint16_t js_pad; /* 2: padding necessary for alignment */
+ uint32_t js_dummy2[26];
+ unsigned char js_uuid[16];
+ unsigned char js_label[16];
+ unsigned char js_loguuid[16];
+};
+
+static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct jfs_super_block *js;
+
+ js = blkid_probe_get_sb(pr, mag, struct jfs_super_block);
+ if (!js)
+ return -1;
+ if (le32_to_cpu(js->js_bsize) != (1 << le16_to_cpu(js->js_l2bsize)))
+ return 1;
+ if (le32_to_cpu(js->js_pbsize) != (1 << le16_to_cpu(js->js_l2pbsize)))
+ return 1;
+ if ((le16_to_cpu(js->js_l2bsize) - le16_to_cpu(js->js_l2pbsize)) !=
+ le16_to_cpu(js->js_l2bfactor))
+ return 1;
+
+ if (strlen((char *) js->js_label))
+ blkid_probe_set_label(pr, js->js_label, sizeof(js->js_label));
+ blkid_probe_set_uuid(pr, js->js_uuid);
+ return 0;
+}
+
+
+const struct blkid_idinfo jfs_idinfo =
+{
+ .name = "jfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_jfs,
+ .magics =
+ {
+ { .magic = "JFS1", .len = 4, .kboff = 32 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/jmicron_raid.c b/shlibs/blkid/src/probers/jmicron_raid.c
new file mode 100644
index 000000000..ae852f8ff
--- /dev/null
+++ b/shlibs/blkid/src/probers/jmicron_raid.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct jm_metadata {
+ int8_t signature[2];
+ uint8_t minor_version;
+ uint8_t major_version;
+ uint16_t checksum;
+};
+
+#define JM_SIGNATURE "JM"
+
+static int probe_jmraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct jm_metadata *jm;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 1) * 0x200;
+ jm = (struct jm_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct jm_metadata));
+ if (!jm)
+ return -1;
+ if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0)
+ return -1;
+ if (blkid_probe_sprintf_version(pr, "%u.%u",
+ jm->major_version, jm->minor_version) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo jmraid_idinfo = {
+ .name = "jmicron_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_jmraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/linux_raid.c b/shlibs/blkid/src/probers/linux_raid.c
new file mode 100644
index 000000000..a5926561d
--- /dev/null
+++ b/shlibs/blkid/src/probers/linux_raid.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct mdp0_super_block {
+ uint32_t md_magic;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint32_t patch_version;
+ uint32_t gvalid_words;
+ uint32_t set_uuid0;
+ uint32_t ctime;
+ uint32_t level;
+ uint32_t size;
+ uint32_t nr_disks;
+ uint32_t raid_disks;
+ uint32_t md_minor;
+ uint32_t not_persistent;
+ uint32_t set_uuid1;
+ uint32_t set_uuid2;
+ uint32_t set_uuid3;
+};
+
+struct mdp1_super_block {
+ uint32_t magic;
+ uint32_t major_version;
+ uint32_t feature_map;
+ uint32_t pad0;
+ uint8_t set_uuid[16];
+ uint8_t set_name[32];
+};
+
+#define MD_RESERVED_BYTES 0x10000
+#define MD_SB_MAGIC 0xa92b4efc
+
+static int probe_raid0(blkid_probe pr, off_t off)
+{
+ struct mdp0_super_block *mdp0;
+ union {
+ uint32_t ints[4];
+ uint8_t bytes[16];
+ } uuid;
+
+ if (pr->size < 0x10000)
+ return -1;
+ mdp0 = (struct mdp0_super_block *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct mdp0_super_block));
+ if (!mdp0)
+ return -1;
+
+ memset(uuid.ints, 0, sizeof(uuid.ints));
+
+ if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
+ uuid.ints[0] = swab32(mdp0->set_uuid0);
+ if (le32_to_cpu(mdp0->minor_version >= 90)) {
+ uuid.ints[1] = swab32(mdp0->set_uuid1);
+ uuid.ints[2] = swab32(mdp0->set_uuid2);
+ uuid.ints[3] = swab32(mdp0->set_uuid3);
+ }
+ if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
+ le32_to_cpu(mdp0->major_version),
+ le32_to_cpu(mdp0->minor_version),
+ le32_to_cpu(mdp0->patch_version)) != 0)
+ return -1;
+
+ } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
+ uuid.ints[0] = mdp0->set_uuid0;
+ if (be32_to_cpu(mdp0->minor_version >= 90)) {
+ uuid.ints[1] = mdp0->set_uuid1;
+ uuid.ints[2] = mdp0->set_uuid2;
+ uuid.ints[3] = mdp0->set_uuid3;
+ }
+ if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
+ be32_to_cpu(mdp0->major_version),
+ be32_to_cpu(mdp0->minor_version),
+ be32_to_cpu(mdp0->patch_version)) != 0)
+ return -1;
+ } else
+ return -1;
+
+ if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0)
+ return -1;
+
+ return 0;
+}
+
+static int probe_raid1(blkid_probe pr, off_t off)
+{
+ struct mdp1_super_block *mdp1;
+
+ mdp1 = (struct mdp1_super_block *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct mdp1_super_block));
+ if (!mdp1)
+ return -1;
+ if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC)
+ return -1;
+ if (le32_to_cpu(mdp1->major_version) != 1)
+ return -1;
+ if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0)
+ return -1;
+ if (blkid_probe_set_label(pr, mdp1->set_name,
+ sizeof(mdp1->set_name)) != 0)
+ return -1;
+
+ return 0;
+}
+
+int probe_raid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ const char *ver = NULL;
+
+ if (pr->size > MD_RESERVED_BYTES) {
+ /* version 0 at the end of the device */
+ uint64_t sboff = (pr->size & ~(MD_RESERVED_BYTES - 1))
+ - MD_RESERVED_BYTES;
+ if (probe_raid0(pr, sboff) == 0)
+ return 0;
+
+ /* version 1.0 at the end of the device */
+ sboff = (pr->size & ~(0x1000 - 1)) - 0x2000;
+ if (probe_raid1(pr, sboff) == 0)
+ ver = "1.0";
+ }
+
+ if (!ver) {
+ /* version 1.1 at the start of the device */
+ if (probe_raid1(pr, 0) == 0)
+ ver = "1.1";
+
+ /* version 1.2 at 4k offset from the start */
+ else if (probe_raid1(pr, 0x1000) == 0)
+ ver = "1.2";
+ }
+
+ if (ver) {
+ blkid_probe_set_version(pr, ver);
+ return 0;
+ }
+ return -1;
+}
+
+
+const struct blkid_idinfo linuxraid_idinfo = {
+ .name = "linux_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_raid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/lsi_raid.c b/shlibs/blkid/src/probers/lsi_raid.c
new file mode 100644
index 000000000..d9ac4e12e
--- /dev/null
+++ b/shlibs/blkid/src/probers/lsi_raid.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct lsi_metadata {
+ uint8_t sig[6];
+};
+
+
+#define LSI_SIGNATURE "$XIDE$"
+
+static int probe_lsiraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct lsi_metadata *lsi;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 1) * 0x200;
+ lsi = (struct lsi_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct lsi_metadata));
+ if (!lsi)
+ return -1;
+
+ if (memcmp(lsi->sig, LSI_SIGNATURE, sizeof(LSI_SIGNATURE)-1) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo lsiraid_idinfo = {
+ .name = "lsi_mega_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_lsiraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/luks.c b/shlibs/blkid/src/probers/luks.c
new file mode 100644
index 000000000..2fe4ff3b4
--- /dev/null
+++ b/shlibs/blkid/src/probers/luks.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+#define LUKS_CIPHERNAME_L 32
+#define LUKS_CIPHERMODE_L 32
+#define LUKS_HASHSPEC_L 32
+#define LUKS_DIGESTSIZE 20
+#define LUKS_SALTSIZE 32
+#define LUKS_MAGIC_L 6
+#define UUID_STRING_L 40
+
+struct luks_phdr {
+ uint8_t magic[LUKS_MAGIC_L];
+ uint16_t version;
+ uint8_t cipherName[LUKS_CIPHERNAME_L];
+ uint8_t cipherMode[LUKS_CIPHERMODE_L];
+ uint8_t hashSpec[LUKS_HASHSPEC_L];
+ uint32_t payloadOffset;
+ uint32_t keyBytes;
+ uint8_t mkDigest[LUKS_DIGESTSIZE];
+ uint8_t mkDigestSalt[LUKS_SALTSIZE];
+ uint32_t mkDigestIterations;
+ uint8_t uuid[UUID_STRING_L];
+};
+
+static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct luks_phdr *header;
+
+ header = blkid_probe_get_sb(pr, mag, struct luks_phdr);
+ if (header == NULL)
+ return -1;
+
+ blkid_probe_strncpy_uuid(pr, (unsigned char *) header->uuid,
+ sizeof(header->uuid));
+ blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(header->version));
+ return 0;
+}
+
+const struct blkid_idinfo luks_idinfo =
+{
+ .name = "crypto_LUKS",
+ .usage = BLKID_USAGE_CRYPTO,
+ .probefunc = probe_luks,
+ .magics =
+ {
+ { .magic = "LUKS\xba\xbe", .len = 6 },
+ { NULL }
+ }
+};
diff --git a/shlibs/blkid/src/probers/lvm.c b/shlibs/blkid/src/probers/lvm.c
new file mode 100644
index 000000000..1a4e6bffe
--- /dev/null
+++ b/shlibs/blkid/src/probers/lvm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+#define LVM2_ID_LEN 32
+
+struct lvm2_pv_label_header {
+ /* label_header */
+ uint8_t id[8]; /* LABELONE */
+ uint64_t sector_xl; /* Sector number of this label */
+ uint32_t crc_xl; /* From next field to end of sector */
+ uint32_t offset_xl; /* Offset from start of struct to contents */
+ uint8_t type[8]; /* LVM2 001 */
+ /* pv_header */
+ uint8_t pv_uuid[LVM2_ID_LEN];
+} __attribute__ ((packed));
+
+#define LVM2_LABEL_SIZE 512
+static unsigned int lvm2_calc_crc(const void *buf, unsigned int size)
+{
+ static const unsigned int crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ unsigned int i, crc = 0xf597a6cf;
+ const uint8_t *data = (const uint8_t *) buf;
+
+ for (i = 0; i < size; i++) {
+ crc ^= *data++;
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+ return crc;
+}
+
+static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ int sector = mag->kboff << 1;
+ struct lvm2_pv_label_header *label;
+ char *p, *q, uuid[40];
+ unsigned int i, b;
+ unsigned char *buf;
+
+ buf = blkid_probe_get_buffer(pr,
+ mag->kboff << 10,
+ 512 + sizeof(struct lvm2_pv_label_header));
+ if (!buf)
+ return -1;
+
+ /* buf is at 0k or 1k offset; find label inside */
+ if (memcmp(buf, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *) buf;
+ } else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *)(buf + 512);
+ sector++;
+ } else {
+ return 1;
+ }
+
+ if (le64_to_cpu(label->sector_xl) != (unsigned) sector)
+ return 1;
+
+ if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
+ ((char *) &label->offset_xl - (char *) label)) !=
+ le32_to_cpu(label->crc_xl)) {
+ DBG(DEBUG_PROBE,
+ printf("LVM2: label checksum incorrect at sector %d\n",
+ sector));
+ return 1;
+ }
+
+ for (i = 0, b = 1, p = uuid, q = (char *) label->pv_uuid; i <= 32;
+ i++, b <<= 1) {
+ if (b & 0x4444440)
+ *p++ = '-';
+ *p++ = *q++;
+ }
+
+ uuid[LVM2_ID_LEN+6] = '\0';
+ blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid),
+ "%s", uuid);
+
+ /* the mag->magic is the same string as label->type,
+ * but zero terminated */
+ blkid_probe_set_version(pr, mag->magic);
+ return 0;
+}
+
+
+/* NOTE: the original libblkid uses "lvm2pv" as a name */
+const struct blkid_idinfo lvm2_idinfo =
+{
+ .name = "LVM2_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_lvm2,
+ .magics =
+ {
+ { .magic = "LVM2 001", .len = 8, .sboff = 0x218 },
+ { .magic = "LVM2 001", .len = 8, .sboff = 0x018 },
+ { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x018 },
+ { .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x218 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo lvm1_idinfo =
+{
+ .name = "LVM1_member",
+ .usage = BLKID_USAGE_RAID,
+ .magics =
+ {
+ { .magic = "HM", .len = 2, .sboff = 0x400 },
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/minix.c b/shlibs/blkid/src/probers/minix.c
new file mode 100644
index 000000000..b29b9a427
--- /dev/null
+++ b/shlibs/blkid/src/probers/minix.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include "blkidP.h"
+
+static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ /* for more details see magic strings below */
+ switch(mag->magic[1]) {
+ case '\023':
+ blkid_probe_set_version(pr, "1");
+ break;
+ case '\044':
+ blkid_probe_set_version(pr, "2");
+ break;
+ case '\115':
+ blkid_probe_set_version(pr, "3");
+ break;
+ }
+ return 0;
+}
+
+const struct blkid_idinfo minix_idinfo =
+{
+ .name = "minix",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_minix,
+ .magics =
+ {
+ /* version 1 */
+ { .magic = "\177\023", .len = 2, .kboff = 1, .sboff = 0x10 },
+ { .magic = "\217\023", .len = 2, .kboff = 1, .sboff = 0x10 },
+
+ /* version 2 */
+ { .magic = "\150\044", .len = 2, .kboff = 1, .sboff = 0x10 },
+ { .magic = "\170\044", .len = 2, .kboff = 1, .sboff = 0x10 },
+
+ /* version 3 */
+ { .magic = "\132\115", .len = 2, .kboff = 1, .sboff = 0x18 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/netware.c b/shlibs/blkid/src/probers/netware.c
new file mode 100644
index 000000000..722506f87
--- /dev/null
+++ b/shlibs/blkid/src/probers/netware.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct netware_super_block {
+ uint8_t SBH_Signature[4];
+ uint16_t SBH_VersionMajor;
+ uint16_t SBH_VersionMinor;
+ uint16_t SBH_VersionMediaMajor;
+ uint16_t SBH_VersionMediaMinor;
+ uint32_t SBH_ItemsMoved;
+ uint8_t SBH_InternalID[16];
+ uint32_t SBH_PackedSize;
+ uint32_t SBH_Checksum;
+ uint32_t supersyncid;
+ int64_t superlocation[4];
+ uint32_t physSizeUsed;
+ uint32_t sizeUsed;
+ uint32_t superTimeStamp;
+ uint32_t reserved0[1];
+ int64_t SBH_LoggedPoolDataBlk;
+ int64_t SBH_PoolDataBlk;
+ uint8_t SBH_OldInternalID[16];
+ uint32_t SBH_PoolToLVStartUTC;
+ uint32_t SBH_PoolToLVEndUTC;
+ uint16_t SBH_VersionMediaMajorCreate;
+ uint16_t SBH_VersionMediaMinorCreate;
+ uint32_t SBH_BlocksMoved;
+ uint32_t SBH_TempBTSpBlk;
+ uint32_t SBH_TempFTSpBlk;
+ uint32_t SBH_TempFTSpBlk1;
+ uint32_t SBH_TempFTSpBlk2;
+ uint32_t nssMagicNumber;
+ uint32_t poolClassID;
+ uint32_t poolID;
+ uint32_t createTime;
+ int64_t SBH_LoggedVolumeDataBlk;
+ int64_t SBH_VolumeDataBlk;
+ int64_t SBH_SystemBeastBlkNum;
+ uint64_t totalblocks;
+ uint16_t SBH_Name[64];
+ uint8_t SBH_VolumeID[16];
+ uint8_t SBH_PoolID[16];
+ uint8_t SBH_PoolInternalID[16];
+ uint64_t SBH_Lsn;
+ uint32_t SBH_SS_Enabled;
+ uint32_t SBH_SS_CreateTime;
+ uint8_t SBH_SS_OriginalPoolID[16];
+ uint8_t SBH_SS_OriginalVolumeID[16];
+ uint8_t SBH_SS_Guid[16];
+ uint16_t SBH_SS_OriginalName[64];
+ uint32_t reserved2[64-(2+46)];
+} __attribute__((__packed__));
+
+static int probe_netware(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct netware_super_block *nw;
+
+ nw = blkid_probe_get_sb(pr, mag, struct netware_super_block);
+ if (!nw)
+ return -1;
+
+ blkid_probe_set_uuid(pr, nw->SBH_PoolID);
+
+ blkid_probe_sprintf_version(pr, "%u.%02u",
+ le16_to_cpu(nw->SBH_VersionMediaMajor),
+ le16_to_cpu(nw->SBH_VersionMediaMinor));
+
+ return 0;
+}
+
+const struct blkid_idinfo netware_idinfo =
+{
+ .name = "nss",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_netware,
+ .magics =
+ {
+ { .magic = "SPB5", .len = 4, .kboff = 4 },
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/ntfs.c b/shlibs/blkid/src/probers/ntfs.c
new file mode 100644
index 000000000..55a186a38
--- /dev/null
+++ b/shlibs/blkid/src/probers/ntfs.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "blkidP.h"
+
+struct ntfs_super_block {
+ uint8_t jump[3];
+ uint8_t oem_id[8];
+ uint8_t bios_parameter_block[25];
+ uint16_t unused[2];
+ uint64_t number_of_sectors;
+ uint64_t mft_cluster_location;
+ uint64_t mft_mirror_cluster_location;
+ int8_t cluster_per_mft_record;
+ uint8_t reserved1[3];
+ int8_t cluster_per_index_record;
+ uint8_t reserved2[3];
+ uint64_t volume_serial;
+ uint16_t checksum;
+};
+
+struct master_file_table_record {
+ uint32_t magic;
+ uint16_t usa_ofs;
+ uint16_t usa_count;
+ uint64_t lsn;
+ uint16_t sequence_number;
+ uint16_t link_count;
+ uint16_t attrs_offset;
+ uint16_t flags;
+ uint32_t bytes_in_use;
+ uint32_t bytes_allocated;
+} __attribute__((__packed__));
+
+struct file_attribute {
+ uint32_t type;
+ uint32_t len;
+ uint8_t non_resident;
+ uint8_t name_len;
+ uint16_t name_offset;
+ uint16_t flags;
+ uint16_t instance;
+ uint32_t value_len;
+ uint16_t value_offset;
+} __attribute__((__packed__));
+
+#define MFT_RECORD_VOLUME 3
+#define MFT_RECORD_ATTR_VOLUME_NAME 0x60
+#define MFT_RECORD_ATTR_VOLUME_INFO 0x70
+#define MFT_RECORD_ATTR_OBJECT_ID 0x40
+#define MFT_RECORD_ATTR_END 0xffffffffu
+
+static int probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ntfs_super_block *ns;
+ struct master_file_table_record *mft;
+ struct file_attribute *attr;
+ unsigned char label_str[129], *cp;
+ int bytes_per_sector, sectors_per_cluster;
+ int mft_record_size, attr_off, attr_len;
+ unsigned int i, attr_type, val_len;
+ int val_off;
+ uint64_t nr_clusters;
+ blkid_loff_t off;
+ unsigned char *buf_mft, *val;
+
+ ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block);
+ if (!ns)
+ return -1;
+
+ bytes_per_sector = ns->bios_parameter_block[0] +
+ (ns->bios_parameter_block[1] << 8);
+ sectors_per_cluster = ns->bios_parameter_block[2];
+
+ if ((bytes_per_sector < 512) || (sectors_per_cluster == 0))
+ return 1;
+
+ if (ns->cluster_per_mft_record < 0)
+ mft_record_size = 1 << (0 - ns->cluster_per_mft_record);
+ else
+ mft_record_size = ns->cluster_per_mft_record *
+ sectors_per_cluster * bytes_per_sector;
+ nr_clusters = le64_to_cpu(ns->number_of_sectors) / sectors_per_cluster;
+
+ if ((le64_to_cpu(ns->mft_cluster_location) > nr_clusters) ||
+ (le64_to_cpu(ns->mft_mirror_cluster_location) > nr_clusters))
+ return 1;
+
+ off = le64_to_cpu(ns->mft_mirror_cluster_location) *
+ bytes_per_sector * sectors_per_cluster;
+
+ buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size);
+ if (!buf_mft)
+ return 1;
+
+ if (memcmp(buf_mft, "FILE", 4))
+ return 1;
+
+ off = le64_to_cpu(ns->mft_cluster_location) * bytes_per_sector *
+ sectors_per_cluster;
+
+ buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size);
+ if (!buf_mft)
+ return 1;
+
+ if (memcmp(buf_mft, "FILE", 4))
+ return 1;
+
+ off += MFT_RECORD_VOLUME * mft_record_size;
+
+ buf_mft = blkid_probe_get_buffer(pr, off, mft_record_size);
+ if (!buf_mft)
+ return 1;
+
+ if (memcmp(buf_mft, "FILE", 4))
+ return 1;
+
+ mft = (struct master_file_table_record *) buf_mft;
+
+ attr_off = le16_to_cpu(mft->attrs_offset);
+ label_str[0] = 0;
+
+ while (1) {
+ attr = (struct file_attribute *) (buf_mft + attr_off);
+ attr_len = le16_to_cpu(attr->len);
+ attr_type = le32_to_cpu(attr->type);
+ val_off = le16_to_cpu(attr->value_offset);
+ val_len = le32_to_cpu(attr->value_len);
+
+ attr_off += attr_len;
+
+ if ((attr_off > mft_record_size) ||
+ (attr_len == 0))
+ break;
+
+ if (attr_type == MFT_RECORD_ATTR_END)
+ break;
+
+ if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) {
+ if (val_len > sizeof(label_str))
+ val_len = sizeof(label_str)-1;
+
+ for (i=0, cp=label_str; i < val_len; i+=2,cp++) {
+ val = ((uint8_t *) attr) + val_off + i;
+ *cp = val[0];
+ if (val[1])
+ *cp = '?';
+ }
+ *cp = 0;
+ }
+ }
+
+ blkid_probe_sprintf_uuid(pr,
+ (unsigned char *) &ns->volume_serial,
+ sizeof(ns->volume_serial),
+ "%016" PRIX64, le64_to_cpu(ns->volume_serial));
+ if (label_str[0])
+ blkid_probe_set_label(pr, label_str, strlen((char *)label_str));
+ return 0;
+}
+
+
+const struct blkid_idinfo ntfs_idinfo =
+{
+ .name = "ntfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ntfs,
+ .magics =
+ {
+ { .magic = "NTFS ", .len = 8, .sboff = 3 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/nvidia_raid.c b/shlibs/blkid/src/probers/nvidia_raid.c
new file mode 100644
index 000000000..76361763c
--- /dev/null
+++ b/shlibs/blkid/src/probers/nvidia_raid.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct nv_metadata {
+ uint8_t vendor[8];
+ uint32_t size;
+ uint32_t chksum;
+ uint16_t version;
+};
+
+#define NVIDIA_SIGNATURE "NVIDIA"
+
+static int probe_nvraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct nv_metadata *nv;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 2) * 0x200;
+ nv = (struct nv_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct nv_metadata));
+ if (!nv)
+ return -1;
+
+ if (memcmp(nv->vendor, NVIDIA_SIGNATURE, sizeof(NVIDIA_SIGNATURE)-1) != 0)
+ return -1;
+
+ if (blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(nv->version)) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo nvraid_idinfo = {
+ .name = "nvidia_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_nvraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/ocfs.c b/shlibs/blkid/src/probers/ocfs.c
new file mode 100644
index 000000000..f9bd11aae
--- /dev/null
+++ b/shlibs/blkid/src/probers/ocfs.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 1999, 2001 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct ocfs_volume_header {
+ unsigned char minor_version[4];
+ unsigned char major_version[4];
+ unsigned char signature[128];
+ char mount[128];
+ unsigned char mount_len[2];
+} __attribute__((packed));
+
+struct ocfs_volume_label {
+ unsigned char disk_lock[48];
+ char label[64];
+ unsigned char label_len[2];
+ unsigned char vol_id[16];
+ unsigned char vol_id_len[2];
+} __attribute__((packed));
+
+#define ocfsmajor(o) ( (uint32_t) o.major_version[0] \
+ + (((uint32_t) o.major_version[1]) << 8) \
+ + (((uint32_t) o.major_version[2]) << 16) \
+ + (((uint32_t) o.major_version[3]) << 24))
+
+#define ocfsminor(o) ( (uint32_t) o.minor_version[0] \
+ + (((uint32_t) o.minor_version[1]) << 8) \
+ + (((uint32_t) o.minor_version[2]) << 16) \
+ + (((uint32_t) o.minor_version[3]) << 24))
+
+#define ocfslabellen(o) ((uint32_t)o.label_len[0] + (((uint32_t) o.label_len[1]) << 8))
+#define ocfsmountlen(o) ((uint32_t)o.mount_len[0] + (((uint32_t) o.mount_len[1]) << 8))
+
+struct ocfs2_super_block {
+ uint8_t i_signature[8];
+ uint32_t i_generation;
+ int16_t i_suballoc_slot;
+ uint16_t i_suballoc_bit;
+ uint32_t i_reserved0;
+ uint32_t i_clusters;
+ uint32_t i_uid;
+ uint32_t i_gid;
+ uint64_t i_size;
+ uint16_t i_mode;
+ uint16_t i_links_count;
+ uint32_t i_flags;
+ uint64_t i_atime;
+ uint64_t i_ctime;
+ uint64_t i_mtime;
+ uint64_t i_dtime;
+ uint64_t i_blkno;
+ uint64_t i_last_eb_blk;
+ uint32_t i_fs_generation;
+ uint32_t i_atime_nsec;
+ uint32_t i_ctime_nsec;
+ uint32_t i_mtime_nsec;
+ uint64_t i_reserved1[9];
+ uint64_t i_pad1;
+ uint16_t s_major_rev_level;
+ uint16_t s_minor_rev_level;
+ uint16_t s_mnt_count;
+ int16_t s_max_mnt_count;
+ uint16_t s_state;
+ uint16_t s_errors;
+ uint32_t s_checkinterval;
+ uint64_t s_lastcheck;
+ uint32_t s_creator_os;
+ uint32_t s_feature_compat;
+ uint32_t s_feature_incompat;
+ uint32_t s_feature_ro_compat;
+ uint64_t s_root_blkno;
+ uint64_t s_system_dir_blkno;
+ uint32_t s_blocksize_bits;
+ uint32_t s_clustersize_bits;
+ uint16_t s_max_slots;
+ uint16_t s_reserved1;
+ uint32_t s_reserved2;
+ uint64_t s_first_cluster_group;
+ uint8_t s_label[64];
+ uint8_t s_uuid[16];
+} __attribute__((packed));
+
+struct oracle_asm_disk_label {
+ char dummy[32];
+ char dl_tag[8];
+ char dl_id[24];
+} __attribute__((packed));
+
+static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ unsigned char *buf;
+ struct ocfs_volume_header ovh;
+ struct ocfs_volume_label ovl;
+ uint32_t maj, min;
+
+ /* header */
+ buf = blkid_probe_get_buffer(pr, mag->kboff << 10,
+ sizeof(struct ocfs_volume_header));
+ if (!buf)
+ return -1;
+ memcpy(&ovh, buf, sizeof(ovh));
+
+ /* label */
+ buf = blkid_probe_get_buffer(pr, (mag->kboff << 10) + 512,
+ sizeof(struct ocfs_volume_label));
+ if (!buf)
+ return -1;
+ memcpy(&ovl, buf, sizeof(ovl));
+
+ maj = ocfsmajor(ovh);
+ min = ocfsminor(ovh);
+
+ if (maj == 1)
+ blkid_probe_set_value(pr, "SEC_TYPE",
+ (unsigned char *) "ocfs1", sizeof("ocfs1"));
+ else if (maj >= 9)
+ blkid_probe_set_value(pr, "SEC_TYPE",
+ (unsigned char *) "ntocfs", sizeof("ntocfs"));
+
+ blkid_probe_set_label(pr, (unsigned char *) ovl.label,
+ ocfslabellen(ovl));
+ blkid_probe_set_value(pr, "MOUNT", (unsigned char *) ovh.mount,
+ ocfsmountlen(ovh));
+ blkid_probe_set_uuid(pr, ovl.vol_id);
+ blkid_probe_sprintf_version(pr, "%u.%u", maj, min);
+ return 0;
+}
+
+static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct ocfs2_super_block *osb;
+
+ osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block);
+ if (!osb)
+ return -1;
+
+ blkid_probe_set_label(pr, (unsigned char *) osb->s_label, sizeof(osb->s_label));
+ blkid_probe_set_uuid(pr, osb->s_uuid);
+
+ blkid_probe_sprintf_version(pr, "%u.%u",
+ le16_to_cpu(osb->s_major_rev_level),
+ le16_to_cpu(osb->s_minor_rev_level));
+
+ return 0;
+}
+
+static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct oracle_asm_disk_label *dl;
+
+ dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label);
+ if (!dl)
+ return -1;
+
+ blkid_probe_set_label(pr, (unsigned char *) dl->dl_id, sizeof(dl->dl_id));
+ return 0;
+}
+
+
+const struct blkid_idinfo ocfs_idinfo =
+{
+ .name = "ocfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ocfs,
+ .magics =
+ {
+ { .magic = "OracleCFS", .len = 9, .kboff = 8 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo ocfs2_idinfo =
+{
+ .name = "ocfs2",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ocfs2,
+ .magics =
+ {
+ { .magic = "OCFSV2", .len = 6, .kboff = 1 },
+ { .magic = "OCFSV2", .len = 6, .kboff = 2 },
+ { .magic = "OCFSV2", .len = 6, .kboff = 4 },
+ { .magic = "OCFSV2", .len = 6, .kboff = 8 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo oracleasm_idinfo =
+{
+ .name = "oracleasm",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_oracleasm,
+ .magics =
+ {
+ { .magic = "ORCLDISK", .len = 8, .sboff = 32 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/probers.h b/shlibs/blkid/src/probers/probers.h
new file mode 100644
index 000000000..c3b227743
--- /dev/null
+++ b/shlibs/blkid/src/probers/probers.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#ifndef _BLKID_PROBE_H
+#define _BLKID_PROBE_H
+
+extern const struct blkid_idinfo cramfs_idinfo;
+extern const struct blkid_idinfo swap_idinfo;
+extern const struct blkid_idinfo swsuspend_idinfo;
+extern const struct blkid_idinfo adraid_idinfo;
+extern const struct blkid_idinfo ddfraid_idinfo;
+extern const struct blkid_idinfo iswraid_idinfo;
+extern const struct blkid_idinfo jmraid_idinfo;
+extern const struct blkid_idinfo lsiraid_idinfo;
+extern const struct blkid_idinfo nvraid_idinfo;
+extern const struct blkid_idinfo pdcraid_idinfo;
+extern const struct blkid_idinfo silraid_idinfo;
+extern const struct blkid_idinfo viaraid_idinfo;
+extern const struct blkid_idinfo linuxraid_idinfo;
+extern const struct blkid_idinfo ext4dev_idinfo;
+extern const struct blkid_idinfo ext4_idinfo;
+extern const struct blkid_idinfo ext3_idinfo;
+extern const struct blkid_idinfo ext2_idinfo;
+extern const struct blkid_idinfo jbd_idinfo;
+extern const struct blkid_idinfo jfs_idinfo;
+extern const struct blkid_idinfo xfs_idinfo;
+extern const struct blkid_idinfo gfs_idinfo;
+extern const struct blkid_idinfo gfs2_idinfo;
+extern const struct blkid_idinfo romfs_idinfo;
+extern const struct blkid_idinfo ocfs_idinfo;
+extern const struct blkid_idinfo ocfs2_idinfo;
+extern const struct blkid_idinfo oracleasm_idinfo;
+extern const struct blkid_idinfo reiser_idinfo;
+extern const struct blkid_idinfo reiser4_idinfo;
+extern const struct blkid_idinfo hfs_idinfo;
+extern const struct blkid_idinfo hfsplus_idinfo;
+extern const struct blkid_idinfo ntfs_idinfo;
+extern const struct blkid_idinfo iso9660_idinfo;
+extern const struct blkid_idinfo udf_idinfo;
+extern const struct blkid_idinfo vxfs_idinfo;
+extern const struct blkid_idinfo minix_idinfo;
+extern const struct blkid_idinfo vfat_idinfo;
+extern const struct blkid_idinfo ufs_idinfo;
+extern const struct blkid_idinfo hpfs_idinfo;
+extern const struct blkid_idinfo lvm2_idinfo;
+extern const struct blkid_idinfo lvm1_idinfo;
+extern const struct blkid_idinfo luks_idinfo;
+extern const struct blkid_idinfo highpoint37x_idinfo;
+extern const struct blkid_idinfo highpoint45x_idinfo;
+extern const struct blkid_idinfo squashfs_idinfo;
+extern const struct blkid_idinfo netware_idinfo;
+extern const struct blkid_idinfo sysv_idinfo;
+extern const struct blkid_idinfo xenix_idinfo;
+extern const struct blkid_idinfo btrfs_idinfo;
+extern const struct blkid_idinfo zfs_idinfo;
+
+#endif /* _BLKID_PROBE_H */
diff --git a/shlibs/blkid/src/probers/promise_raid.c b/shlibs/blkid/src/probers/promise_raid.c
new file mode 100644
index 000000000..295400925
--- /dev/null
+++ b/shlibs/blkid/src/probers/promise_raid.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct promise_metadata {
+ uint8_t sig[24];
+};
+
+#define PDC_CONFIG_OFF 0x1200
+#define PDC_SIGNATURE "Promise Technology, Inc."
+
+static int probe_pdcraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ unsigned int i;
+ static unsigned int sectors[] = {
+ 63, 255, 256, 16, 399, 0
+ };
+
+ if (pr->size < 0x40000)
+ return -1;
+
+ for (i = 0; sectors[i] != 0; i++) {
+ uint64_t off;
+ struct promise_metadata *pdc;
+
+ off = ((pr->size / 0x200) - sectors[i]) * 0x200;
+ pdc = (struct promise_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct promise_metadata));
+ if (!pdc)
+ return -1;
+
+ if (memcmp(pdc->sig, PDC_SIGNATURE,
+ sizeof(PDC_SIGNATURE) - 1) == 0)
+ return 0;
+ }
+ return -1;
+}
+
+const struct blkid_idinfo pdcraid_idinfo = {
+ .name = "promise_fasttrack_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_pdcraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/reiserfs.c b/shlibs/blkid/src/probers/reiserfs.c
new file mode 100644
index 000000000..29e1faa0f
--- /dev/null
+++ b/shlibs/blkid/src/probers/reiserfs.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 1999, 2001 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct reiserfs_super_block {
+ uint32_t rs_blocks_count;
+ uint32_t rs_free_blocks;
+ uint32_t rs_root_block;
+ uint32_t rs_journal_block;
+ uint32_t rs_journal_dev;
+ uint32_t rs_orig_journal_size;
+ uint32_t rs_dummy2[5];
+ uint16_t rs_blocksize;
+ uint16_t rs_dummy3[3];
+ unsigned char rs_magic[12];
+ uint32_t rs_dummy4[5];
+ unsigned char rs_uuid[16];
+ char rs_label[16];
+};
+
+struct reiser4_super_block {
+ unsigned char rs4_magic[16];
+ uint16_t rs4_dummy[2];
+ unsigned char rs4_uuid[16];
+ unsigned char rs4_label[16];
+ uint64_t rs4_dummy2;
+};
+
+static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct reiserfs_super_block *rs;
+ unsigned int blocksize;
+
+ rs = blkid_probe_get_sb(pr, mag, struct reiserfs_super_block);
+ if (!rs)
+ return -1;
+
+ blocksize = le16_to_cpu(rs->rs_blocksize);
+
+ /* The blocksize must be at least 1k */
+ if ((blocksize >> 10) == 0)
+ return -BLKID_ERR_PARAM;
+
+ /* If the superblock is inside the journal, we have the wrong one */
+ if (mag->kboff / (blocksize >> 10) > le32_to_cpu(rs->rs_journal_block))
+ return -BLKID_ERR_BIG;
+
+ /* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
+ if (mag->magic[6] == '2' || mag->magic[6] == '3') {
+ if (*rs->rs_label)
+ blkid_probe_set_label(pr,
+ (unsigned char *) rs->rs_label,
+ sizeof(rs->rs_label));
+ blkid_probe_set_uuid(pr, rs->rs_uuid);
+ }
+
+ if (mag->magic[6] == '3')
+ blkid_probe_set_version(pr, "JR");
+ else if (mag->magic[6] == '2')
+ blkid_probe_set_version(pr, "3.6");
+ else
+ blkid_probe_set_version(pr, "3.5");
+
+ return 0;
+}
+
+static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct reiser4_super_block *rs4;
+
+ rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block);
+ if (!rs4)
+ return -1;
+
+ if (*rs4->rs4_label)
+ blkid_probe_set_label(pr, rs4->rs4_label, sizeof(rs4->rs4_label));
+ blkid_probe_set_uuid(pr, rs4->rs4_uuid);
+ blkid_probe_set_version(pr, "4");
+
+ return 0;
+}
+
+
+const struct blkid_idinfo reiser_idinfo =
+{
+ .name = "reiser",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_reiser,
+ .magics =
+ {
+ { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 0x34 },
+ { .magic = "ReIsEr2Fs", .len = 9, .kboff = 64, .sboff = 0x34 },
+ { .magic = "ReIsEr3Fs", .len = 9, .kboff = 64, .sboff = 0x34 },
+ { .magic = "ReIsErFs", .len = 8, .kboff = 64, .sboff = 0x34 },
+ { .magic = "ReIsErFs", .len = 8, .kboff = 8, .sboff = 20 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo reiser4_idinfo =
+{
+ .name = "reiser4",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_reiser4,
+ .magics =
+ {
+ { .magic = "ReIsEr4", .len = 7, .kboff = 64 },
+ { NULL }
+ }
+};
+
+
+
+
diff --git a/shlibs/blkid/src/probers/romfs.c b/shlibs/blkid/src/probers/romfs.c
new file mode 100644
index 000000000..b5c20ab7f
--- /dev/null
+++ b/shlibs/blkid/src/probers/romfs.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1999, 2001 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct romfs_super_block {
+ unsigned char ros_magic[8];
+ uint32_t ros_dummy1[2];
+ unsigned char ros_volume[16];
+};
+
+static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct romfs_super_block *ros;
+
+ ros = blkid_probe_get_sb(pr, mag, struct romfs_super_block);
+ if (!ros)
+ return -1;
+
+ if (strlen((char *) ros->ros_volume))
+ blkid_probe_set_label(pr, ros->ros_volume,
+ sizeof(ros->ros_volume));
+ return 0;
+}
+
+const struct blkid_idinfo romfs_idinfo =
+{
+ .name = "romfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_romfs,
+ .magics =
+ {
+ { .magic = "-rom1fs-", .len = 8 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/silicon_raid.c b/shlibs/blkid/src/probers/silicon_raid.c
new file mode 100644
index 000000000..a65d79a83
--- /dev/null
+++ b/shlibs/blkid/src/probers/silicon_raid.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct silicon_metadata {
+ uint8_t unknown0[0x2E];
+ uint8_t ascii_version[0x36 - 0x2E];
+ uint8_t diskname[0x56 - 0x36];
+ uint8_t unknown1[0x60 - 0x56];
+ uint32_t magic;
+ uint32_t unknown1a[0x6C - 0x64];
+ uint32_t array_sectors_low;
+ uint32_t array_sectors_high;
+ uint8_t unknown2[0x78 - 0x74];
+ uint32_t thisdisk_sectors;
+ uint8_t unknown3[0x100 - 0x7C];
+ uint8_t unknown4[0x104 - 0x100];
+ uint16_t product_id;
+ uint16_t vendor_id;
+ uint16_t minor_ver;
+ uint16_t major_ver;
+};
+
+#define SILICON_MAGIC 0x2F000000
+
+
+static int probe_silraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct silicon_metadata *sil;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200) - 1) * 0x200;
+
+ sil = (struct silicon_metadata *)
+ blkid_probe_get_buffer(pr, off,
+ sizeof(struct silicon_metadata));
+ if (!sil)
+ return -1;
+
+ if (le32_to_cpu(sil->magic) != SILICON_MAGIC)
+ return -1;
+
+ if (blkid_probe_sprintf_version(pr, "%u.%u",
+ le16_to_cpu(sil->major_ver),
+ le16_to_cpu(sil->minor_ver)) != 0)
+ return -1;
+
+ return 0;
+}
+
+const struct blkid_idinfo silraid_idinfo = {
+ .name = "silicon_medley_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_silraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/squashfs.c b/shlibs/blkid/src/probers/squashfs.c
new file mode 100644
index 000000000..74f53bfb6
--- /dev/null
+++ b/shlibs/blkid/src/probers/squashfs.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "bitops.h" /* swab16() */
+#include "blkidP.h"
+
+struct sqsh_super_block {
+ uint32_t s_magic;
+ uint32_t inodes;
+ uint32_t bytes_used_2;
+ uint32_t uid_start_2;
+ uint32_t guid_start_2;
+ uint32_t inode_table_start_2;
+ uint32_t directory_table_start_2;
+ uint16_t s_major;
+ uint16_t s_minor;
+};
+
+static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct sqsh_super_block *sq;
+
+ sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block);
+ if (!sq)
+ return -1;
+
+ if (strcmp(mag->magic, "sqsh") == 0 ||
+ strcmp(mag->magic, "qshs") == 0)
+ blkid_probe_sprintf_version(pr, "%u.%u",
+ sq->s_major,
+ sq->s_minor);
+ else
+ blkid_probe_sprintf_version(pr, "%u.%u",
+ swab16(sq->s_major),
+ swab16(sq->s_minor));
+ return 0;
+}
+
+const struct blkid_idinfo squashfs_idinfo =
+{
+ .name = "squashfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_squashfs,
+ .magics =
+ {
+ { .magic = "sqsh", .len = 4 },
+ { .magic = "hsqs", .len = 4 }, /* swap */
+
+ /* LZMA version */
+ { .magic = "qshs", .len = 4 },
+ { .magic = "shsq", .len = 4 }, /* swap */
+ { NULL }
+ }
+};
+
+
diff --git a/shlibs/blkid/src/probers/swap.c b/shlibs/blkid/src/probers/swap.c
new file mode 100644
index 000000000..86eb94c61
--- /dev/null
+++ b/shlibs/blkid/src/probers/swap.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+/* linux-2.6/include/linux/swap.h */
+struct swap_header_v1_2 {
+ /* char bootbits[1024]; */ /* Space for disklabel etc. */
+ uint32_t version;
+ uint32_t lastpage;
+ uint32_t nr_badpages;
+ unsigned char uuid[16];
+ unsigned char volume[16];
+ uint32_t padding[117];
+ uint32_t badpages[1];
+};
+
+#define PAGESIZE_MIN 0xff6 /* 4086 (arm, i386, ...) */
+#define PAGESIZE_MAX 0xfff6 /* 65526 (ia64) */
+
+
+static int swap_set_info(blkid_probe pr, const char *version)
+{
+ struct swap_header_v1_2 *hdr;
+
+ /* Swap header always located at offset of 1024 bytes */
+ hdr = (struct swap_header_v1_2 *) blkid_probe_get_buffer(pr, 1024,
+ sizeof(struct swap_header_v1_2));
+ if (!hdr)
+ return -1;
+
+ /* SWAPSPACE2 - check for wrong version or zeroed pagecount */
+ if (strcmp(version, "2") == 0 &&
+ (hdr->version != 1 || hdr->lastpage == 0))
+ return -1;
+
+ /* arbitrary sanity check.. is there any garbage down there? */
+ if (hdr->padding[32] == 0 && hdr->padding[33] == 0) {
+ if (hdr->volume[0] && blkid_probe_set_label(pr, hdr->volume,
+ sizeof(hdr->volume)) < 0)
+ return -1;
+ if (hdr->uuid[0] && blkid_probe_set_uuid(pr, hdr->uuid) < 0)
+ return -1;
+ }
+
+ blkid_probe_set_version(pr, version);
+ return 0;
+}
+
+static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ if (!mag)
+ return -1;
+
+ if (!memcmp(mag->magic, "SWAP-SPACE", mag->len)) {
+ /* swap v0 doesn't support LABEL or UUID */
+ blkid_probe_set_version(pr, "1");
+ return 0;
+
+ } else if (!memcmp(mag->magic, "SWAPSPACE2", mag->len))
+ return swap_set_info(pr, "2");
+
+ return -1;
+}
+
+static int probe_swsuspend(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ if (!mag)
+ return -1;
+ if (!memcmp(mag->magic, "S1SUSPEND", mag->len))
+ return swap_set_info(pr, "s1suspend");
+ if (!memcmp(mag->magic, "S2SUSPEND", mag->len))
+ return swap_set_info(pr, "s2suspend");
+ if (!memcmp(mag->magic, "ULSUSPEND", mag->len))
+ return swap_set_info(pr, "ulsuspend");
+ if (!memcmp(mag->magic, "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", mag->len))
+ return swap_set_info(pr, "tuxonice");
+
+ return -1; /* no signature detected */
+}
+
+const struct blkid_idinfo swap_idinfo =
+{
+ .name = "swap",
+ .usage = BLKID_USAGE_OTHER,
+ .probefunc = probe_swap,
+ .magics =
+ {
+ { "SWAP-SPACE", 10, 0, 0xff6 },
+ { "SWAPSPACE2", 10, 0, 0xff6 },
+ { "SWAP-SPACE", 10, 0, 0x1ff6 },
+ { "SWAPSPACE2", 10, 0, 0x1ff6 },
+ { "SWAP-SPACE", 10, 0, 0x3ff6 },
+ { "SWAPSPACE2", 10, 0, 0x3ff6 },
+ { "SWAP-SPACE", 10, 0, 0x7ff6 },
+ { "SWAPSPACE2", 10, 0, 0x7ff6 },
+ { "SWAP-SPACE", 10, 0, 0xfff6 },
+ { "SWAPSPACE2", 10, 0, 0xfff6 },
+ { NULL }
+ }
+};
+
+
+const struct blkid_idinfo swsuspend_idinfo =
+{
+ .name = "swsupend",
+ .usage = BLKID_USAGE_OTHER,
+ .probefunc = probe_swsuspend,
+ .magics =
+ {
+ { "S1SUSPEND", 9, 0, 0xff6 },
+ { "S2SUSPEND", 9, 0, 0xff6 },
+ { "ULSUSPEND", 9, 0, 0xff6 },
+ { "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8, 0, 0xff6 },
+ { "S1SUSPEND", 9, 0, 0x1ff6 },
+ { "S2SUSPEND", 9, 0, 0x1ff6 },
+ { "ULSUSPEND", 9, 0, 0x1ff6 },
+ { "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8, 0, 0x1ff6 },
+ { "S1SUSPEND", 9, 0, 0x3ff6 },
+ { "S2SUSPEND", 9, 0, 0x3ff6 },
+ { "ULSUSPEND", 9, 0, 0x3ff6 },
+ { "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8, 0, 0x3ff6 },
+ { "S1SUSPEND", 9, 0, 0x7ff6 },
+ { "S2SUSPEND", 9, 0, 0x7ff6 },
+ { "ULSUSPEND", 9, 0, 0x7ff6 },
+ { "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8, 0, 0x7ff6 },
+ { "S1SUSPEND", 9, 0, 0xfff6 },
+ { "S2SUSPEND", 9, 0, 0xfff6 },
+ { "ULSUSPEND", 9, 0, 0xfff6 },
+ { "\xed\xc3\x02\xe9\x98\x56\xe5\x0c", 8, 0, 0xfff6 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/sysv.c b/shlibs/blkid/src/probers/sysv.c
new file mode 100644
index 000000000..933163a27
--- /dev/null
+++ b/shlibs/blkid/src/probers/sysv.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This is written from sratch according to Linux kernel fs/sysv/super.c file.
+ * It seems that sysv probing code in libvolume_id and also in the original
+ * blkid is useless.
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+#define XENIX_NICINOD 100
+#define XENIX_NICFREE 100
+
+struct xenix_super_block {
+ uint16_t s_isize;
+ uint32_t s_fsize;
+ uint16_t s_nfree;
+ uint32_t s_free[XENIX_NICFREE];
+ uint16_t s_ninode;
+ uint16_t s_inode[XENIX_NICINOD];
+ uint8_t s_flock;
+ uint8_t s_ilock;
+ uint8_t s_fmod;
+ uint8_t s_ronly;
+ uint32_t s_time;
+ uint32_t s_tfree;
+ uint16_t s_tinode;
+ uint16_t s_dinfo[4];
+ uint8_t s_fname[6];
+ uint8_t s_fpack[6];
+ uint8_t s_clean;
+ uint8_t s_fill[371];
+ uint32_t s_magic;
+ uint32_t s_type;
+};
+
+
+#define SYSV_NICINOD 100
+#define SYSV_NICFREE 50
+
+struct sysv_super_block
+{
+ uint16_t s_isize;
+ uint16_t s_pad0;
+ uint32_t s_fsize;
+ uint16_t s_nfree;
+ uint16_t s_pad1;
+ uint32_t s_free[SYSV_NICFREE];
+ uint16_t s_ninode;
+ uint16_t s_pad2;
+ uint16_t s_inode[SYSV_NICINOD];
+ uint8_t s_flock;
+ uint8_t s_ilock;
+ uint8_t s_fmod;
+ uint8_t s_ronly;
+ uint32_t s_time;
+ uint16_t s_dinfo[4];
+ uint32_t s_tfree;
+ uint16_t s_tinode;
+ uint16_t s_pad3;
+ uint8_t s_fname[6];
+ uint8_t s_fpack[6];
+ uint32_t s_fill[12];
+ uint32_t s_state;
+ uint32_t s_magic;
+ uint32_t s_type;
+};
+
+static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct xenix_super_block *sb;
+
+ sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block);
+ if (!sb)
+ return -1;
+ blkid_probe_set_label(pr, sb->s_fname, sizeof(sb->s_fname));
+ return 0;
+}
+
+#define SYSV_BLOCK_SIZE 1024
+
+/* Note that we don't probe for Coherent FS, this FS does not have
+ * magic string. (It requires to probe fname/fpack field..)
+ */
+static int probe_sysv(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct sysv_super_block *sb;
+ int blocks[] = {0, 9, 15, 18};
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(blocks); i++) {
+ int off = blocks[i] * SYSV_BLOCK_SIZE + SYSV_BLOCK_SIZE/2;
+
+ sb = (struct sysv_super_block *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct sysv_super_block));
+ if (!sb)
+ return -1;
+
+ if (sb->s_magic == cpu_to_le32(0xfd187e20) ||
+ sb->s_magic == cpu_to_be32(0xfd187e20)) {
+ blkid_probe_set_label(pr, sb->s_fname, sizeof(sb->s_fname));
+ return 0;
+ }
+ }
+ return 1;
+}
+
+const struct blkid_idinfo xenix_idinfo =
+{
+ .name = "xenix",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_xenix,
+ .magics =
+ {
+ { .magic = "\x2b\x55\x44", .len = 3, .kboff = 1, .sboff = 0x400 },
+ { .magic = "\x44\x55\x2b", .len = 3, .kboff = 1, .sboff = 0x400 },
+ { NULL }
+ }
+};
+
+const struct blkid_idinfo sysv_idinfo =
+{
+ .name = "sysv",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_sysv,
+
+ /* SYSV is BE and LE and superblock could be on four positions. It's
+ * simpler to probe for the magic string by .probefunc().
+ */
+ .magics = BLKID_NONE_MAGIC
+};
+
diff --git a/shlibs/blkid/src/probers/udf.c b/shlibs/blkid/src/probers/udf.c
new file mode 100644
index 000000000..5f4046d6d
--- /dev/null
+++ b/shlibs/blkid/src/probers/udf.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct volume_descriptor {
+ struct descriptor_tag {
+ uint16_t id;
+ uint16_t version;
+ uint8_t checksum;
+ uint8_t reserved;
+ uint16_t serial;
+ uint16_t crc;
+ uint16_t crc_len;
+ uint32_t location;
+ } tag;
+ union {
+ struct anchor_descriptor {
+ uint32_t length;
+ uint32_t location;
+ } anchor;
+ struct primary_descriptor {
+ uint32_t seq_num;
+ uint32_t desc_num;
+ struct dstring {
+ uint8_t clen;
+ uint8_t c[31];
+ } ident;
+ } primary;
+ } type;
+};
+
+struct volume_structure_descriptor {
+ uint8_t type;
+ uint8_t id[5];
+ uint8_t version;
+};
+
+#define UDF_VSD_OFFSET 0x8000
+
+static int probe_udf(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct volume_descriptor *vd;
+ struct volume_structure_descriptor *vsd;
+ unsigned int bs;
+ unsigned int b;
+ unsigned int type;
+ unsigned int count;
+ unsigned int loc;
+
+ /* search Volume Sequence Descriptor (VSD) to get the logical
+ * block size of the volume */
+ for (bs = 0x800; bs < 0x8000; bs += 0x800) {
+ vsd = (struct volume_structure_descriptor *)
+ blkid_probe_get_buffer(pr,
+ UDF_VSD_OFFSET + bs,
+ sizeof(*vsd));
+ if (!vsd)
+ return 1;
+ if (vsd->id[0] != '\0')
+ goto nsr;
+ }
+ return -1;
+
+nsr:
+ /* search the list of VSDs for a NSR descriptor */
+ for (b = 0; b < 64; b++) {
+ vsd = (struct volume_structure_descriptor *)
+ blkid_probe_get_buffer(pr,
+ UDF_VSD_OFFSET + (b * bs),
+ sizeof(*vsd));
+ if (!vsd)
+ return -1;
+ if (vsd->id[0] == '\0')
+ return -1;
+ if (memcmp(vsd->id, "NSR02", 5) == 0)
+ goto anchor;
+ if (memcmp(vsd->id, "NSR03", 5) == 0)
+ goto anchor;
+ }
+ return -1;
+
+anchor:
+ /* read Anchor Volume Descriptor (AVDP) */
+ vd = (struct volume_descriptor *)
+ blkid_probe_get_buffer(pr, 256 * bs, sizeof(*vd));
+ if (!vd)
+ return -1;
+
+ type = le16_to_cpu(vd->tag.id);
+ if (type != 2) /* TAG_ID_AVDP */
+ return 0;
+
+ /* get desriptor list address and block count */
+ count = le32_to_cpu(vd->type.anchor.length) / bs;
+ loc = le32_to_cpu(vd->type.anchor.location);
+
+ /* pick the primary descriptor from the list */
+ for (b = 0; b < count; b++) {
+ vd = (struct volume_descriptor *)
+ blkid_probe_get_buffer(pr, (loc + b) * bs, sizeof(*vd));
+ if (!vd)
+ return -1;
+
+ type = le16_to_cpu(vd->tag.id);
+ if (type == 0)
+ break;
+ if (le32_to_cpu(vd->tag.location) != loc + b)
+ break;
+ if (type == 1) { /* TAG_ID_PVD */
+ uint8_t clen = vd->type.primary.ident.clen;
+
+ if (clen == 8)
+ blkid_probe_set_label(pr,
+ vd->type.primary.ident.c, 31);
+ else if (clen == 16)
+ blkid_probe_set_utf8label(pr,
+ vd->type.primary.ident.c,
+ 31, BLKID_ENC_UTF16BE);
+ }
+ }
+
+ return 0;
+}
+
+
+const struct blkid_idinfo udf_idinfo =
+{
+ .name = "udf",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_udf,
+ .flags = BLKID_IDINFO_TOLERANT,
+ .magics =
+ {
+ { .magic = "BEA01", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "BOOT2", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "CD001", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "CDW02", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "NSR02", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "NSR03", .len = 5, .kboff = 32, .sboff = 1 },
+ { .magic = "TEA01", .len = 5, .kboff = 32, .sboff = 1 },
+ { NULL }
+ }
+};
diff --git a/shlibs/blkid/src/probers/ufs.c b/shlibs/blkid/src/probers/ufs.c
new file mode 100644
index 000000000..fe9870d84
--- /dev/null
+++ b/shlibs/blkid/src/probers/ufs.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct ufs_super_block {
+ uint32_t fs_link;
+ uint32_t fs_rlink;
+ uint32_t fs_sblkno;
+ uint32_t fs_cblkno;
+ uint32_t fs_iblkno;
+ uint32_t fs_dblkno;
+ uint32_t fs_cgoffset;
+ uint32_t fs_cgmask;
+ uint32_t fs_time;
+ uint32_t fs_size;
+ uint32_t fs_dsize;
+ uint32_t fs_ncg;
+ uint32_t fs_bsize;
+ uint32_t fs_fsize;
+ uint32_t fs_frag;
+ uint32_t fs_minfree;
+ uint32_t fs_rotdelay;
+ uint32_t fs_rps;
+ uint32_t fs_bmask;
+ uint32_t fs_fmask;
+ uint32_t fs_bshift;
+ uint32_t fs_fshift;
+ uint32_t fs_maxcontig;
+ uint32_t fs_maxbpg;
+ uint32_t fs_fragshift;
+ uint32_t fs_fsbtodb;
+ uint32_t fs_sbsize;
+ uint32_t fs_csmask;
+ uint32_t fs_csshift;
+ uint32_t fs_nindir;
+ uint32_t fs_inopb;
+ uint32_t fs_nspf;
+ uint32_t fs_optim;
+ uint32_t fs_npsect_state;
+ uint32_t fs_interleave;
+ uint32_t fs_trackskew;
+ uint32_t fs_id[2];
+ uint32_t fs_csaddr;
+ uint32_t fs_cssize;
+ uint32_t fs_cgsize;
+ uint32_t fs_ntrak;
+ uint32_t fs_nsect;
+ uint32_t fs_spc;
+ uint32_t fs_ncyl;
+ uint32_t fs_cpg;
+ uint32_t fs_ipg;
+ uint32_t fs_fpg;
+ struct ufs_csum {
+ uint32_t cs_ndir;
+ uint32_t cs_nbfree;
+ uint32_t cs_nifree;
+ uint32_t cs_nffree;
+ } fs_cstotal;
+ int8_t fs_fmod;
+ int8_t fs_clean;
+ int8_t fs_ronly;
+ int8_t fs_flags;
+ union {
+ struct {
+ int8_t fs_fsmnt[512];
+ uint32_t fs_cgrotor;
+ uint32_t fs_csp[31];
+ uint32_t fs_maxcluster;
+ uint32_t fs_cpc;
+ uint16_t fs_opostbl[16][8];
+ } fs_u1;
+ struct {
+ int8_t fs_fsmnt[468];
+ uint8_t fs_volname[32];
+ uint64_t fs_swuid;
+ int32_t fs_pad;
+ uint32_t fs_cgrotor;
+ uint32_t fs_ocsp[28];
+ uint32_t fs_contigdirs;
+ uint32_t fs_csp;
+ uint32_t fs_maxcluster;
+ uint32_t fs_active;
+ int32_t fs_old_cpc;
+ int32_t fs_maxbsize;
+ int64_t fs_sparecon64[17];
+ int64_t fs_sblockloc;
+ struct ufs2_csum_total {
+ uint64_t cs_ndir;
+ uint64_t cs_nbfree;
+ uint64_t cs_nifree;
+ uint64_t cs_nffree;
+ uint64_t cs_numclusters;
+ uint64_t cs_spare[3];
+ } fs_cstotal;
+ struct ufs_timeval {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } fs_time;
+ int64_t fs_size;
+ int64_t fs_dsize;
+ uint64_t fs_csaddr;
+ int64_t fs_pendingblocks;
+ int32_t fs_pendinginodes;
+ } fs_u2;
+ } fs_u11;
+ union {
+ struct {
+ int32_t fs_sparecon[53];
+ int32_t fs_reclaim;
+ int32_t fs_sparecon2[1];
+ int32_t fs_state;
+ uint32_t fs_qbmask[2];
+ uint32_t fs_qfmask[2];
+ } fs_sun;
+ struct {
+ int32_t fs_sparecon[53];
+ int32_t fs_reclaim;
+ int32_t fs_sparecon2[1];
+ uint32_t fs_npsect;
+ uint32_t fs_qbmask[2];
+ uint32_t fs_qfmask[2];
+ } fs_sunx86;
+ struct {
+ int32_t fs_sparecon[50];
+ int32_t fs_contigsumsize;
+ int32_t fs_maxsymlinklen;
+ int32_t fs_inodefmt;
+ uint32_t fs_maxfilesize[2];
+ uint32_t fs_qbmask[2];
+ uint32_t fs_qfmask[2];
+ int32_t fs_state;
+ } fs_44;
+ } fs_u2;
+ int32_t fs_postblformat;
+ int32_t fs_nrpos;
+ int32_t fs_postbloff;
+ int32_t fs_rotbloff;
+ uint32_t fs_magic;
+ uint8_t fs_space[1];
+};
+
+#define UFS_MAGIC 0x00011954
+#define UFS2_MAGIC 0x19540119
+#define UFS_MAGIC_FEA 0x00195612
+#define UFS_MAGIC_LFN 0x00095014
+
+static int probe_ufs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ int offsets[] = { 0, 8, 64, 256 };
+ int mags[] = { UFS2_MAGIC, UFS_MAGIC, UFS_MAGIC_FEA, UFS_MAGIC_LFN };
+ int i;
+ uint32_t magic;
+ struct ufs_super_block *ufs;
+
+ for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+ uint32_t magLE, magBE;
+ int y;
+
+ ufs = (struct ufs_super_block *)
+ blkid_probe_get_buffer(pr,
+ offsets[i] * 1024,
+ sizeof(struct ufs_super_block));
+ if (!ufs)
+ return -1;
+
+ magBE = be32_to_cpu(ufs->fs_magic);
+ magLE = le32_to_cpu(ufs->fs_magic);
+
+ for (y = 0; y < ARRAY_SIZE(mags); y++) {
+ if (magLE == mags[y] || magBE == mags[y]) {
+ magic = mags[y];
+ goto found;
+ }
+ }
+ }
+
+ return 1;
+
+found:
+ if (magic == UFS2_MAGIC) {
+ blkid_probe_set_version(pr, "2");
+ blkid_probe_set_label(pr, ufs->fs_u11.fs_u2.fs_volname,
+ sizeof(ufs->fs_u11.fs_u2.fs_volname));
+ } else
+ blkid_probe_set_version(pr, "1");
+
+ return 0;
+}
+
+/*
+ * According to libvolume_id the UFS superblock could be on four positions.
+ * The original libblkid has checked one position (.kboff=8) only.
+ *
+ * We know four UFS magic strings and UFS could be both little-endian and
+ * big-endian. ... so we have:
+ *
+ * 4 position * 4 string * 2 version = 32 magic strings
+ *
+ * It seems simpler to check for these string in probing function that hardcode
+ * all in the .magic array.
+ */
+const struct blkid_idinfo ufs_idinfo =
+{
+ .name = "ufs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_ufs,
+ .magics = BLKID_NONE_MAGIC
+};
+
diff --git a/shlibs/blkid/src/probers/vfat.c b/shlibs/blkid/src/probers/vfat.c
new file mode 100644
index 000000000..a83175c0b
--- /dev/null
+++ b/shlibs/blkid/src/probers/vfat.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+/* Yucky misaligned values */
+struct vfat_super_block {
+/* 00*/ unsigned char vs_ignored[3];
+/* 03*/ unsigned char vs_sysid[8];
+/* 0b*/ unsigned char vs_sector_size[2];
+/* 0d*/ uint8_t vs_cluster_size;
+/* 0e*/ uint16_t vs_reserved;
+/* 10*/ uint8_t vs_fats;
+/* 11*/ unsigned char vs_dir_entries[2];
+/* 13*/ unsigned char vs_sectors[2];
+/* 15*/ unsigned char vs_media;
+/* 16*/ uint16_t vs_fat_length;
+/* 18*/ uint16_t vs_secs_track;
+/* 1a*/ uint16_t vs_heads;
+/* 1c*/ uint32_t vs_hidden;
+/* 20*/ uint32_t vs_total_sect;
+/* 24*/ uint32_t vs_fat32_length;
+/* 28*/ uint16_t vs_flags;
+/* 2a*/ uint8_t vs_version[2];
+/* 2c*/ uint32_t vs_root_cluster;
+/* 30*/ uint16_t vs_fsinfo_sector;
+/* 32*/ uint16_t vs_backup_boot;
+/* 34*/ uint16_t vs_reserved2[6];
+/* 40*/ unsigned char vs_unknown[3];
+/* 43*/ unsigned char vs_serno[4];
+/* 47*/ unsigned char vs_label[11];
+/* 52*/ unsigned char vs_magic[8];
+/* 5a*/ unsigned char vs_dummy2[164];
+/*1fe*/ unsigned char vs_pmagic[2];
+};
+
+/* Yucky misaligned values */
+struct msdos_super_block {
+/* 00*/ unsigned char ms_ignored[3];
+/* 03*/ unsigned char ms_sysid[8];
+/* 0b*/ unsigned char ms_sector_size[2];
+/* 0d*/ uint8_t ms_cluster_size;
+/* 0e*/ uint16_t ms_reserved;
+/* 10*/ uint8_t ms_fats;
+/* 11*/ unsigned char ms_dir_entries[2];
+/* 13*/ unsigned char ms_sectors[2];
+/* 15*/ unsigned char ms_media;
+/* 16*/ uint16_t ms_fat_length;
+/* 18*/ uint16_t ms_secs_track;
+/* 1a*/ uint16_t ms_heads;
+/* 1c*/ uint32_t ms_hidden;
+/* 20*/ uint32_t ms_total_sect;
+/* 24*/ unsigned char ms_unknown[3];
+/* 27*/ unsigned char ms_serno[4];
+/* 2b*/ unsigned char ms_label[11];
+/* 36*/ unsigned char ms_magic[8];
+/* 3d*/ unsigned char ms_dummy2[192];
+/*1fe*/ unsigned char ms_pmagic[2];
+};
+
+struct vfat_dir_entry {
+ uint8_t name[11];
+ uint8_t attr;
+ uint16_t time_creat;
+ uint16_t date_creat;
+ uint16_t time_acc;
+ uint16_t date_acc;
+ uint16_t cluster_high;
+ uint16_t time_write;
+ uint16_t date_write;
+ uint16_t cluster_low;
+ uint32_t size;
+};
+
+struct fat32_fsinfo {
+ uint8_t signature1[4];
+ uint32_t reserved1[120];
+ uint8_t signature2[4];
+ uint32_t free_clusters;
+ uint32_t next_cluster;
+ uint32_t reserved2[4];
+};
+
+/* maximum number of clusters */
+#define FAT12_MAX 0xFF4
+#define FAT16_MAX 0xFFF4
+#define FAT32_MAX 0x0FFFFFF6
+
+#define FAT_ATTR_VOLUME_ID 0x08
+#define FAT_ATTR_DIR 0x10
+#define FAT_ATTR_LONG_NAME 0x0f
+#define FAT_ATTR_MASK 0x3f
+#define FAT_ENTRY_FREE 0xe5
+
+static const char *no_name = "NO NAME ";
+
+static unsigned char *search_fat_label(struct vfat_dir_entry *dir, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (dir[i].name[0] == 0x00)
+ break;
+
+ if ((dir[i].name[0] == FAT_ENTRY_FREE) ||
+ (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) ||
+ ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME))
+ continue;
+
+ if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) ==
+ FAT_ATTR_VOLUME_ID) {
+ return dir[i].name;
+ }
+ }
+ return 0;
+}
+
+/*
+ * The FAT filesystem could be without a magic string in superblock
+ * (e.g. old floppies). This heuristic for FAT detection is inspired
+ * by libvolume_id and the Linux kernel.
+ */
+static int probe_fat_nomagic(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct msdos_super_block *ms;
+
+ ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
+ if (!ms)
+ return -1;
+
+ /* heads check */
+ if (ms->ms_heads == 0)
+ return 1;
+
+ /* cluster size check*/
+ if (ms->ms_cluster_size == 0 ||
+ (ms->ms_cluster_size & (ms->ms_cluster_size-1)))
+ return 1;
+
+ /* media check */
+ if (ms->ms_media < 0xf8 && ms->ms_media != 0xf0)
+ return 1;
+
+ /* fat counts(Linux kernel expects at least 1 FAT table) */
+ if (!ms->ms_fats)
+ return 1;
+
+ /*
+ * OS/2 and apparently DFSee will place a FAT12/16-like
+ * pseudo-superblock in the first 512 bytes of non-FAT
+ * filesystems --- at least JFS and HPFS, and possibly others.
+ * So we explicitly check for those filesystems at the
+ * FAT12/16 filesystem magic field identifier, and if they are
+ * present, we rule this out as a FAT filesystem, despite the
+ * FAT-like pseudo-header.
+ */
+ if ((memcmp(ms->ms_magic, "JFS ", 8) == 0) ||
+ (memcmp(ms->ms_magic, "HPFS ", 8) == 0))
+ return 1;
+
+ return 0;
+}
+
+/* FAT label extraction from the root directory taken from Kay
+ * Sievers's volume_id library */
+static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct vfat_super_block *vs;
+ struct msdos_super_block *ms;
+ struct vfat_dir_entry *dir;
+ const unsigned char *vol_label = 0, *tmp;
+ unsigned char *vol_serno;
+ int maxloop = 100;
+ uint16_t sector_size, dir_entries, reserved;
+ uint32_t sect_count, fat_size, dir_size, cluster_count, fat_length;
+ uint32_t buf_size, start_data_sect, next, root_start, root_dir_entries;
+ const char *version = NULL;
+
+
+ /* non-standard magic strings */
+ if (mag->len <= 2 && probe_fat_nomagic(pr, mag) != 0)
+ return 1;
+
+ vs = blkid_probe_get_sb(pr, mag, struct vfat_super_block);
+ if (!vs)
+ return -1;
+
+ ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
+ if (!ms)
+ return -1;
+
+ /* sector size check */
+ tmp = (unsigned char *) &ms->ms_sector_size;
+ sector_size = tmp[0] + (tmp[1] << 8);
+ if (sector_size != 0x200 && sector_size != 0x400 &&
+ sector_size != 0x800 && sector_size != 0x1000)
+ return 1;
+
+ tmp = (unsigned char *) &ms->ms_dir_entries;
+ dir_entries = tmp[0] + (tmp[1] << 8);
+ reserved = le16_to_cpu(ms->ms_reserved);
+ tmp = (unsigned char *) &ms->ms_sectors;
+ sect_count = tmp[0] + (tmp[1] << 8);
+ if (sect_count == 0)
+ sect_count = le32_to_cpu(ms->ms_total_sect);
+
+ fat_length = le16_to_cpu(ms->ms_fat_length);
+ if (fat_length == 0)
+ fat_length = le32_to_cpu(vs->vs_fat32_length);
+
+ fat_size = fat_length * ms->ms_fats;
+ dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
+ (sector_size-1)) / sector_size;
+
+ cluster_count = sect_count - (reserved + fat_size + dir_size);
+ if (ms->ms_cluster_size == 0)
+ return 1;
+ cluster_count /= ms->ms_cluster_size;
+
+ if (cluster_count > FAT32_MAX)
+ return 1;
+
+ if (ms->ms_fat_length) {
+ /* the label may be an attribute in the root directory */
+ root_start = (reserved + fat_size) * sector_size;
+ root_dir_entries = vs->vs_dir_entries[0] +
+ (vs->vs_dir_entries[1] << 8);
+
+ buf_size = root_dir_entries * sizeof(struct vfat_dir_entry);
+ dir = (struct vfat_dir_entry *)
+ blkid_probe_get_buffer(pr, root_start, buf_size);
+ if (dir)
+ vol_label = search_fat_label(dir, root_dir_entries);
+
+ if (!vol_label || !memcmp(vol_label, no_name, 11))
+ vol_label = ms->ms_label;
+ vol_serno = ms->ms_serno;
+
+ blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "msdos",
+ sizeof("msdos"));
+
+ if (cluster_count < FAT12_MAX)
+ version = "FAT12";
+ else if (cluster_count < FAT16_MAX)
+ version = "FAT16";
+ } else {
+ unsigned char *buf;
+ uint16_t fsinfo_sect;
+
+ /* Search the FAT32 root dir for the label attribute */
+ buf_size = vs->vs_cluster_size * sector_size;
+ start_data_sect = reserved + fat_size;
+
+ version = "FAT32";
+
+ next = le32_to_cpu(vs->vs_root_cluster);
+ while (next && --maxloop) {
+ uint32_t next_sect_off;
+ uint64_t next_off, fat_entry_off;
+ int count;
+
+ next_sect_off = (next - 2) * vs->vs_cluster_size;
+ next_off = (start_data_sect + next_sect_off) *
+ sector_size;
+
+ dir = (struct vfat_dir_entry *)
+ blkid_probe_get_buffer(pr, next_off, buf_size);
+ if (dir == NULL)
+ break;
+
+ count = buf_size / sizeof(struct vfat_dir_entry);
+
+ vol_label = search_fat_label(dir, count);
+ if (vol_label)
+ break;
+
+ /* get FAT entry */
+ fat_entry_off = (reserved * sector_size) +
+ (next * sizeof(uint32_t));
+ buf = blkid_probe_get_buffer(pr, fat_entry_off, buf_size);
+ if (buf == NULL)
+ break;
+
+ /* set next cluster */
+ next = le32_to_cpu(*((uint32_t *) buf) & 0x0fffffff);
+ }
+
+ if (!vol_label || !memcmp(vol_label, no_name, 11))
+ vol_label = vs->vs_label;
+ vol_serno = vs->vs_serno;
+
+ /*
+ * FAT32 should have a valid signature in the fsinfo block,
+ * but also allow all bytes set to '\0', because some volumes
+ * do not set the signature at all.
+ */
+ fsinfo_sect = le16_to_cpu(vs->vs_fsinfo_sector);
+ if (fsinfo_sect) {
+ struct fat32_fsinfo *fsinfo;
+
+ buf = blkid_probe_get_buffer(pr,
+ fsinfo_sect * sector_size,
+ sizeof(struct fat32_fsinfo));
+ if (buf == NULL)
+ return -1;
+
+ fsinfo = (struct fat32_fsinfo *) buf;
+ if (memcmp(fsinfo->signature1, "\x52\x52\x61\x41", 4) != 0 &&
+ memcmp(fsinfo->signature1, "\x00\x00\x00\x00", 4) != 0)
+ return -1;
+ if (memcmp(fsinfo->signature2, "\x72\x72\x41\x61", 4) != 0 &&
+ memcmp(fsinfo->signature2, "\x00\x00\x00\x00", 4) != 0)
+ return -1;
+ }
+ }
+
+ if (vol_label && memcmp(vol_label, no_name, 11))
+ blkid_probe_set_label(pr, (unsigned char *) vol_label, 11);
+
+ /* We can't just print them as %04X, because they are unaligned */
+ blkid_probe_sprintf_uuid(pr, vol_serno, 4, "%02X%02X-%02X%02X",
+ vol_serno[3], vol_serno[2], vol_serno[1], vol_serno[0]);
+
+ if (version)
+ blkid_probe_set_version(pr, version);
+
+ return 0;
+}
+
+
+const struct blkid_idinfo vfat_idinfo =
+{
+ .name = "vfat",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_vfat,
+ .magics =
+ {
+ { .magic = "MSWIN", .len = 5, .sboff = 0x52 },
+ { .magic = "FAT32 ", .len = 8, .sboff = 0x52 },
+ { .magic = "MSDOS", .len = 5, .sboff = 0x36 },
+ { .magic = "FAT16 ", .len = 8, .sboff = 0x36 },
+ { .magic = "FAT12 ", .len = 8, .sboff = 0x36 },
+ { .magic = "\353", .len = 1, },
+ { .magic = "\351", .len = 1, },
+ { .magic = "\125\252", .len = 2, .sboff = 0x1fe },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/via_raid.c b/shlibs/blkid/src/probers/via_raid.c
new file mode 100644
index 000000000..22022fdd5
--- /dev/null
+++ b/shlibs/blkid/src/probers/via_raid.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * Inspired by libvolume_id by
+ * Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct via_metadata {
+ uint16_t signature;
+ uint8_t version_number;
+ struct via_array {
+ uint16_t disk_bit_mask;
+ uint8_t disk_array_ex;
+ uint32_t capacity_low;
+ uint32_t capacity_high;
+ uint32_t serial_checksum;
+ } array;
+ uint32_t serial_checksum[8];
+ uint8_t checksum;
+};
+
+#define VIA_SIGNATURE 0xAA55
+
+/* 8 bit checksum on first 50 bytes of metadata. */
+static uint8_t via_checksum(struct via_metadata *v)
+{
+ uint8_t i = 50, cs = 0;
+
+ while (i--)
+ cs += ((uint8_t*) v)[i];
+
+ return cs == v->checksum;
+}
+
+static int probe_viaraid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ uint64_t off;
+ struct via_metadata *v;
+
+ if (pr->size < 0x10000)
+ return -1;
+
+ off = ((pr->size / 0x200)-1) * 0x200;
+
+ v = (struct via_metadata *)
+ blkid_probe_get_buffer(pr,
+ off,
+ sizeof(struct via_metadata));
+ if (!v)
+ return -1;
+ if (le16_to_cpu(v->signature) != VIA_SIGNATURE)
+ return -1;
+ if (v->version_number > 2)
+ return -1;
+ if (!via_checksum(v))
+ return -1;
+ if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0)
+ return -1;
+ return 0;
+}
+
+const struct blkid_idinfo viaraid_idinfo = {
+ .name = "via_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_viaraid,
+ .magics = BLKID_NONE_MAGIC
+};
+
+
diff --git a/shlibs/blkid/src/probers/vxfs.c b/shlibs/blkid/src/probers/vxfs.c
new file mode 100644
index 000000000..7a27b6c9e
--- /dev/null
+++ b/shlibs/blkid/src/probers/vxfs.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+
+#include "blkidP.h"
+
+struct vxfs_super_block {
+ uint32_t vs_magic;
+ int32_t vs_version;
+};
+
+static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct vxfs_super_block *vxs;
+
+ vxs = blkid_probe_get_sb(pr, mag, struct vxfs_super_block);
+ if (!vxs)
+ return -1;
+
+ blkid_probe_sprintf_version(pr, "%u", (unsigned int) vxs->vs_version);
+ return 0;
+}
+
+
+const struct blkid_idinfo vxfs_idinfo =
+{
+ .name = "vxfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_vxfs,
+ .magics =
+ {
+ { .magic = "\365\374\001\245", .len = 4, .kboff = 1 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/xfs.c b/shlibs/blkid/src/probers/xfs.c
new file mode 100644
index 000000000..fa7914e29
--- /dev/null
+++ b/shlibs/blkid/src/probers/xfs.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999 by Andries Brouwer
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct xfs_super_block {
+ unsigned char xs_magic[4];
+ uint32_t xs_blocksize;
+ uint64_t xs_dblocks;
+ uint64_t xs_rblocks;
+ uint32_t xs_dummy1[2];
+ unsigned char xs_uuid[16];
+ uint32_t xs_dummy2[15];
+ char xs_fname[12];
+ uint32_t xs_dummy3[2];
+ uint64_t xs_icount;
+ uint64_t xs_ifree;
+ uint64_t xs_fdblocks;
+};
+
+static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct xfs_super_block *xs;
+
+ xs = blkid_probe_get_sb(pr, mag, struct xfs_super_block);
+ if (!xs)
+ return -1;
+
+ if (strlen(xs->xs_fname))
+ blkid_probe_set_label(pr, (unsigned char *) xs->xs_fname,
+ sizeof(xs->xs_fname));
+ blkid_probe_set_uuid(pr, xs->xs_uuid);
+ return 0;
+}
+
+const struct blkid_idinfo xfs_idinfo =
+{
+ .name = "xfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_xfs,
+ .magics =
+ {
+ { .magic = "XFSB", .len = 4 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/probers/zfs.c b/shlibs/blkid/src/probers/zfs.c
new file mode 100644
index 000000000..7d39034f6
--- /dev/null
+++ b/shlibs/blkid/src/probers/zfs.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 by Andreas Dilger <adilger@sun.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "blkidP.h"
+
+/* #include <sys/uberblock_impl.h> */
+#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */
+struct zfs_uberblock {
+ uint64_t ub_magic; /* UBERBLOCK_MAGIC */
+ uint64_t ub_version; /* SPA_VERSION */
+ uint64_t ub_txg; /* txg of last sync */
+ uint64_t ub_guid_sum; /* sum of all vdev guids */
+ uint64_t ub_timestamp; /* UTC time of last sync */
+ /*blkptr_t ub_rootbp;*/ /* MOS objset_phys_t */
+};
+
+static int probe_zfs(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ struct zfs_uberblock *ub;
+ int swab_endian;
+ uint64_t spa_version;
+
+ ub = blkid_probe_get_sb(pr, mag, struct zfs_uberblock);
+ if (!ub)
+ return -1;
+
+ swab_endian = (ub->ub_magic == swab64(UBERBLOCK_MAGIC));
+ spa_version = swab_endian ? swab64(ub->ub_version) : ub->ub_version;
+
+ blkid_probe_sprintf_version(pr, "%" PRIu64, spa_version);
+#if 0
+ /* read nvpair data for pool name, pool GUID from the MOS, but
+ * unfortunately this is more complex than it could be */
+ blkid_probe_set_label(pr, pool_name, pool_len));
+ blkid_probe_set_uuid(pr, pool_guid);
+#endif
+ return 0;
+}
+
+const struct blkid_idinfo zfs_idinfo =
+{
+ .name = "zfs",
+ .usage = BLKID_USAGE_FILESYSTEM,
+ .probefunc = probe_zfs,
+ .magics =
+ {
+ { .magic = "\0\0\x02\xf5\xb0\x07\xb1\x0c", .len = 8, .kboff = 8 },
+ { .magic = "\x1c\xb1\x07\xb0\xf5\x02\0\0", .len = 8, .kboff = 8 },
+ { .magic = "\0\0\x02\xf5\xb0\x07\xb1\x0c", .len = 8, .kboff = 264 },
+ { .magic = "\x0c\xb1\x07\xb0\xf5\x02\0\0", .len = 8, .kboff = 264 },
+ { NULL }
+ }
+};
+
diff --git a/shlibs/blkid/src/read.c b/shlibs/blkid/src/read.c
new file mode 100644
index 000000000..b5e9cd024
--- /dev/null
+++ b/shlibs/blkid/src/read.c
@@ -0,0 +1,492 @@
+/*
+ * read.c - read the blkid cache from disk, to avoid scanning all devices
+ *
+ * Copyright (C) 2001, 2003 Theodore Y. Ts'o
+ * Copyright (C) 2001 Andreas Dilger
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#define _XOPEN_SOURCE 600 /* for inclusion of strtoull */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "blkidP.h"
+
+#ifdef HAVE_STRTOULL
+#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */
+#else
+/* FIXME: need to support real strtoull here */
+#define STRTOULL strtoul
+#endif
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef TEST_PROGRAM
+#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev))
+static void debug_dump_dev(blkid_dev dev);
+#endif
+
+/*
+ * File format:
+ *
+ * <device [<NAME="value"> ...]>device_name</device>
+ *
+ * The following tags are required for each entry:
+ * <ID="id"> unique (within this file) ID number of this device
+ * <TIME="time"> (ascii time_t) time this entry was last read from disk
+ * <TYPE="type"> (detected) type of filesystem/data for this partition
+ *
+ * The following tags may be present, depending on the device contents
+ * <LABEL="label"> (user supplied) label (volume name, etc)
+ * <UUID="uuid"> (generated) universally unique identifier (serial no)
+ */
+
+static char *skip_over_blank(char *cp)
+{
+ while (*cp && isspace(*cp))
+ cp++;
+ return cp;
+}
+
+static char *skip_over_word(char *cp)
+{
+ char ch;
+
+ while ((ch = *cp)) {
+ /* If we see a backslash, skip the next character */
+ if (ch == '\\') {
+ cp++;
+ if (*cp == '\0')
+ break;
+ cp++;
+ continue;
+ }
+ if (isspace(ch) || ch == '<' || ch == '>')
+ break;
+ cp++;
+ }
+ return cp;
+}
+
+static char *strip_line(char *line)
+{
+ char *p;
+
+ line = skip_over_blank(line);
+
+ p = line + strlen(line) - 1;
+
+ while (*line) {
+ if (isspace(*p))
+ *p-- = '\0';
+ else
+ break;
+ }
+
+ return line;
+}
+
+#if 0
+static char *parse_word(char **buf)
+{
+ char *word, *next;
+
+ word = *buf;
+ if (*word == '\0')
+ return NULL;
+
+ word = skip_over_blank(word);
+ next = skip_over_word(word);
+ if (*next) {
+ char *end = next - 1;
+ if (*end == '"' || *end == '\'')
+ *end = '\0';
+ *next++ = '\0';
+ }
+ *buf = next;
+
+ if (*word == '"' || *word == '\'')
+ word++;
+ return word;
+}
+#endif
+
+/*
+ * Start parsing a new line from the cache.
+ *
+ * line starts with "<device" return 1 -> continue parsing line
+ * line starts with "<foo", empty, or # return 0 -> skip line
+ * line starts with other, return -BLKID_ERR_CACHE -> error
+ */
+static int parse_start(char **cp)
+{
+ char *p;
+
+ p = strip_line(*cp);
+
+ /* Skip comment or blank lines. We can't just NUL the first '#' char,
+ * in case it is inside quotes, or escaped.
+ */
+ if (*p == '\0' || *p == '#')
+ return 0;
+
+ if (!strncmp(p, "<device", 7)) {
+ DBG(DEBUG_READ, printf("found device header: %8s\n", p));
+ p += 7;
+
+ *cp = p;
+ return 1;
+ }
+
+ if (*p == '<')
+ return 0;
+
+ return -BLKID_ERR_CACHE;
+}
+
+/* Consume the remaining XML on the line (cosmetic only) */
+static int parse_end(char **cp)
+{
+ *cp = skip_over_blank(*cp);
+
+ if (!strncmp(*cp, "</device>", 9)) {
+ DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp));
+ *cp += 9;
+ return 0;
+ }
+
+ return -BLKID_ERR_CACHE;
+}
+
+/*
+ * Allocate a new device struct with device name filled in. Will handle
+ * finding the device on lines of the form:
+ * <device foo=bar>devname</device>
+ * <device>devname<foo>bar</foo></device>
+ */
+static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
+{
+ char *start, *tmp, *end, *name;
+ int ret;
+
+ if ((ret = parse_start(cp)) <= 0)
+ return ret;
+
+ start = tmp = strchr(*cp, '>');
+ if (!start) {
+ DBG(DEBUG_READ,
+ printf("blkid: short line parsing dev: %s\n", *cp));
+ return -BLKID_ERR_CACHE;
+ }
+ start = skip_over_blank(start + 1);
+ end = skip_over_word(start);
+
+ DBG(DEBUG_READ, printf("device should be %*s\n",
+ (int)(end - start), start));
+
+ if (**cp == '>')
+ *cp = end;
+ else
+ (*cp)++;
+
+ *tmp = '\0';
+
+ if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) {
+ DBG(DEBUG_READ,
+ printf("blkid: missing </device> ending: %s\n", end));
+ } else if (tmp)
+ *tmp = '\0';
+
+ if (end - start <= 1) {
+ DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp));
+ return -BLKID_ERR_CACHE;
+ }
+
+ name = blkid_strndup(start, end-start);
+ if (name == NULL)
+ return -BLKID_ERR_MEM;
+
+ DBG(DEBUG_READ, printf("found dev %s\n", name));
+
+ if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) {
+ free(name);
+ return -BLKID_ERR_MEM;
+ }
+
+ free(name);
+ return 1;
+}
+
+/*
+ * Extract a tag of the form NAME="value" from the line.
+ */
+static int parse_token(char **name, char **value, char **cp)
+{
+ char *end;
+
+ if (!name || !value || !cp)
+ return -BLKID_ERR_PARAM;
+
+ if (!(*value = strchr(*cp, '=')))
+ return 0;
+
+ **value = '\0';
+ *name = strip_line(*cp);
+ *value = skip_over_blank(*value + 1);
+
+ if (**value == '"') {
+ end = strchr(*value + 1, '"');
+ if (!end) {
+ DBG(DEBUG_READ,
+ printf("unbalanced quotes at: %s\n", *value));
+ *cp = *value;
+ return -BLKID_ERR_CACHE;
+ }
+ (*value)++;
+ *end = '\0';
+ end++;
+ } else {
+ end = skip_over_word(*value);
+ if (*end) {
+ *end = '\0';
+ end++;
+ }
+ }
+ *cp = end;
+
+ return 1;
+}
+
+/*
+ * Extract a tag of the form <NAME>value</NAME> from the line.
+ */
+/*
+static int parse_xml(char **name, char **value, char **cp)
+{
+ char *end;
+
+ if (!name || !value || !cp)
+ return -BLKID_ERR_PARAM;
+
+ *name = strip_line(*cp);
+
+ if ((*name)[0] != '<' || (*name)[1] == '/')
+ return 0;
+
+ FIXME: finish this.
+}
+*/
+
+/*
+ * Extract a tag from the line.
+ *
+ * Return 1 if a valid tag was found.
+ * Return 0 if no tag found.
+ * Return -ve error code.
+ */
+static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
+{
+ char *name;
+ char *value;
+ int ret;
+
+ if (!cache || !dev)
+ return -BLKID_ERR_PARAM;
+
+ if ((ret = parse_token(&name, &value, cp)) <= 0 /* &&
+ (ret = parse_xml(&name, &value, cp)) <= 0 */)
+ return ret;
+
+ /* Some tags are stored directly in the device struct */
+ if (!strcmp(name, "DEVNO"))
+ dev->bid_devno = STRTOULL(value, 0, 0);
+ else if (!strcmp(name, "PRI"))
+ dev->bid_pri = strtol(value, 0, 0);
+ else if (!strcmp(name, "TIME"))
+ dev->bid_time = STRTOULL(value, 0, 0);
+ else
+ ret = blkid_set_tag(dev, name, value, strlen(value));
+
+ DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value));
+
+ return ret < 0 ? ret : 1;
+}
+
+/*
+ * Parse a single line of data, and return a newly allocated dev struct.
+ * Add the new device to the cache struct, if one was read.
+ *
+ * Lines are of the form <device [TAG="value" ...]>/dev/foo</device>
+ *
+ * Returns -ve value on error.
+ * Returns 0 otherwise.
+ * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL
+ * (e.g. comment lines, unknown XML content, etc).
+ */
+static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
+{
+ blkid_dev dev;
+ int ret;
+
+ if (!cache || !dev_p)
+ return -BLKID_ERR_PARAM;
+
+ *dev_p = NULL;
+
+ DBG(DEBUG_READ, printf("line: %s\n", cp));
+
+ if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
+ return ret;
+
+ dev = *dev_p;
+
+ while ((ret = parse_tag(cache, dev, &cp)) > 0) {
+ ;
+ }
+
+ if (dev->bid_type == NULL) {
+ DBG(DEBUG_READ,
+ printf("blkid: device %s has no TYPE\n",dev->bid_name));
+ blkid_free_dev(dev);
+ }
+
+ DBG(DEBUG_READ, blkid_debug_dump_dev(dev));
+
+ return ret;
+}
+
+/*
+ * Parse the specified filename, and return the data in the supplied or
+ * a newly allocated cache struct. If the file doesn't exist, return a
+ * new empty cache struct.
+ */
+void blkid_read_cache(blkid_cache cache)
+{
+ FILE *file;
+ char buf[4096];
+ int fd, lineno = 0;
+ struct stat st;
+
+ if (!cache)
+ return;
+
+ /*
+ * If the file doesn't exist, then we just return an empty
+ * struct so that the cache can be populated.
+ */
+ if ((fd = open(cache->bic_filename, O_RDONLY)) < 0)
+ return;
+ if (fstat(fd, &st) < 0)
+ goto errout;
+ if ((st.st_mtime == cache->bic_ftime) ||
+ (cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
+ DBG(DEBUG_CACHE, printf("skipping re-read of %s\n",
+ cache->bic_filename));
+ goto errout;
+ }
+
+ DBG(DEBUG_CACHE, printf("reading cache file %s\n",
+ cache->bic_filename));
+
+ file = fdopen(fd, "r");
+ if (!file)
+ goto errout;
+
+ while (fgets(buf, sizeof(buf), file)) {
+ blkid_dev dev;
+ unsigned int end;
+
+ lineno++;
+ if (buf[0] == 0)
+ continue;
+ end = strlen(buf) - 1;
+ /* Continue reading next line if it ends with a backslash */
+ while (buf[end] == '\\' && end < sizeof(buf) - 2 &&
+ fgets(buf + end, sizeof(buf) - end, file)) {
+ end = strlen(buf) - 1;
+ lineno++;
+ }
+
+ if (blkid_parse_line(cache, &dev, buf) < 0) {
+ DBG(DEBUG_READ,
+ printf("blkid: bad format on line %d\n", lineno));
+ continue;
+ }
+ }
+ fclose(file);
+
+ /*
+ * Initially we do not need to write out the cache file.
+ */
+ cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
+ cache->bic_ftime = st.st_mtime;
+
+ return;
+errout:
+ close(fd);
+ return;
+}
+
+#ifdef TEST_PROGRAM
+static void debug_dump_dev(blkid_dev dev)
+{
+ struct list_head *p;
+
+ if (!dev) {
+ printf(" dev: NULL\n");
+ return;
+ }
+
+ printf(" dev: name = %s\n", dev->bid_name);
+ printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
+ printf(" dev: TIME=\"%lld\"\n", (long long)dev->bid_time);
+ printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
+ printf(" dev: flags = 0x%08X\n", dev->bid_flags);
+
+ list_for_each(p, &dev->bid_tags) {
+ blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
+ if (tag)
+ printf(" tag: %s=\"%s\"\n", tag->bit_name,
+ tag->bit_val);
+ else
+ printf(" tag: NULL\n");
+ }
+ printf("\n");
+}
+
+int main(int argc, char**argv)
+{
+ blkid_cache cache = NULL;
+ int ret;
+
+ blkid_init_debug(DEBUG_ALL);
+ if (argc > 2) {
+ fprintf(stderr, "Usage: %s [filename]\n"
+ "Test parsing of the cache (filename)\n", argv[0]);
+ exit(1);
+ }
+ if ((ret = blkid_get_cache(&cache, argv[1])) < 0)
+ fprintf(stderr, "error %d reading cache file %s\n", ret,
+ argv[1] ? argv[1] : BLKID_CACHE_FILE);
+
+ blkid_put_cache(cache);
+
+ return ret;
+}
+#endif
diff --git a/shlibs/blkid/src/resolve.c b/shlibs/blkid/src/resolve.c
new file mode 100644
index 000000000..bf13b8648
--- /dev/null
+++ b/shlibs/blkid/src/resolve.c
@@ -0,0 +1,139 @@
+/*
+ * resolve.c - resolve names and tags into specific devices
+ *
+ * Copyright (C) 2001, 2003 Theodore Ts'o.
+ * Copyright (C) 2001 Andreas Dilger
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "blkidP.h"
+
+/*
+ * Find a tagname (e.g. LABEL or UUID) on a specific device.
+ */
+char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
+ const char *devname)
+{
+ blkid_tag found;
+ blkid_dev dev;
+ blkid_cache c = cache;
+ char *ret = NULL;
+
+ DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname));
+
+ if (!devname)
+ return NULL;
+
+ if (!cache) {
+ if (blkid_get_cache(&c, NULL) < 0)
+ return NULL;
+ }
+
+ if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) &&
+ (found = blkid_find_tag_dev(dev, tagname)))
+ ret = blkid_strdup(found->bit_val);
+
+ if (!cache)
+ blkid_put_cache(c);
+
+ return ret;
+}
+
+/*
+ * Locate a device name from a token (NAME=value string), or (name, value)
+ * pair. In the case of a token, value is ignored. If the "token" is not
+ * of the form "NAME=value" and there is no value given, then it is assumed
+ * to be the actual devname and a copy is returned.
+ */
+char *blkid_get_devname(blkid_cache cache, const char *token,
+ const char *value)
+{
+ blkid_dev dev;
+ blkid_cache c = cache;
+ char *t = 0, *v = 0;
+ char *ret = NULL;
+
+ if (!token)
+ return NULL;
+
+ if (!cache) {
+ if (blkid_get_cache(&c, NULL) < 0)
+ return NULL;
+ }
+
+ DBG(DEBUG_RESOLVE,
+ printf("looking for %s%s%s %s\n", token, value ? "=" : "",
+ value ? value : "", cache ? "in cache" : "from disk"));
+
+ if (!value) {
+ if (!strchr(token, '=')) {
+ ret = blkid_strdup(token);
+ goto out;
+ }
+ blkid_parse_tag_string(token, &t, &v);
+ if (!t || !v)
+ goto out;
+ token = t;
+ value = v;
+ }
+
+ dev = blkid_find_dev_with_tag(c, token, value);
+ if (!dev)
+ goto out;
+
+ ret = blkid_strdup(blkid_dev_devname(dev));
+
+out:
+ free(t);
+ free(v);
+ if (!cache) {
+ blkid_put_cache(c);
+ }
+ return (ret);
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv)
+{
+ char *value;
+ blkid_cache cache;
+
+ blkid_init_debug(DEBUG_ALL);
+ if (argc != 2 && argc != 3) {
+ fprintf(stderr, "Usage:\t%s tagname=value\n"
+ "\t%s tagname devname\n"
+ "Find which device holds a given token or\n"
+ "Find what the value of a tag is in a device\n",
+ argv[0], argv[0]);
+ exit(1);
+ }
+ if (blkid_get_cache(&cache, "/dev/null") < 0) {
+ fprintf(stderr, "Couldn't get blkid cache\n");
+ exit(1);
+ }
+
+ if (argv[2]) {
+ value = blkid_get_tag_value(cache, argv[1], argv[2]);
+ printf("%s has tag %s=%s\n", argv[2], argv[1],
+ value ? value : "<missing>");
+ } else {
+ value = blkid_get_devname(cache, argv[1], NULL);
+ printf("%s has tag %s\n", value ? value : "<none>", argv[1]);
+ }
+ blkid_put_cache(cache);
+ return value ? 0 : 1;
+}
+#endif
diff --git a/shlibs/blkid/src/save.c b/shlibs/blkid/src/save.c
new file mode 100644
index 000000000..bbe6f488e
--- /dev/null
+++ b/shlibs/blkid/src/save.c
@@ -0,0 +1,193 @@
+/*
+ * save.c - write the cache struct to disk
+ *
+ * Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "blkidP.h"
+
+static int save_dev(blkid_dev dev, FILE *file)
+{
+ struct list_head *p;
+
+ if (!dev || dev->bid_name[0] != '/')
+ return 0;
+
+ DBG(DEBUG_SAVE,
+ printf("device %s, type %s\n", dev->bid_name, dev->bid_type ?
+ dev->bid_type : "(null)"));
+
+ fprintf(file,
+ "<device DEVNO=\"0x%04lx\" TIME=\"%ld\"",
+ (unsigned long) dev->bid_devno, (long) dev->bid_time);
+ if (dev->bid_pri)
+ fprintf(file, " PRI=\"%d\"", dev->bid_pri);
+ list_for_each(p, &dev->bid_tags) {
+ blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
+ fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
+ }
+ fprintf(file, ">%s</device>\n", dev->bid_name);
+
+ return 0;
+}
+
+/*
+ * Write out the cache struct to the cache file on disk.
+ */
+int blkid_flush_cache(blkid_cache cache)
+{
+ struct list_head *p;
+ char *tmp = NULL;
+ const char *opened = NULL;
+ const char *filename;
+ FILE *file = NULL;
+ int fd, ret = 0;
+ struct stat st;
+
+ if (!cache)
+ return -BLKID_ERR_PARAM;
+
+ if (list_empty(&cache->bic_devs) ||
+ !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
+ DBG(DEBUG_SAVE, printf("skipping cache file write\n"));
+ return 0;
+ }
+
+ filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
+
+ /* If we can't write to the cache file, then don't even try */
+ if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
+ (ret == 0 && access(filename, W_OK) < 0)) {
+ DBG(DEBUG_SAVE,
+ printf("can't write to cache file %s\n", filename));
+ return 0;
+ }
+
+ /*
+ * Try and create a temporary file in the same directory so
+ * that in case of error we don't overwrite the cache file.
+ * If the cache file doesn't yet exist, it isn't a regular
+ * file (e.g. /dev/null or a socket), or we couldn't create
+ * a temporary file then we open it directly.
+ */
+ if (ret == 0 && S_ISREG(st.st_mode)) {
+ tmp = malloc(strlen(filename) + 8);
+ if (tmp) {
+ sprintf(tmp, "%s-XXXXXX", filename);
+ fd = mkstemp(tmp);
+ if (fd >= 0) {
+ file = fdopen(fd, "w");
+ opened = tmp;
+ }
+ fchmod(fd, 0644);
+ }
+ }
+
+ if (!file) {
+ file = fopen(filename, "w");
+ opened = filename;
+ }
+
+ DBG(DEBUG_SAVE,
+ printf("writing cache file %s (really %s)\n",
+ filename, opened));
+
+ if (!file) {
+ ret = errno;
+ goto errout;
+ }
+
+ list_for_each(p, &cache->bic_devs) {
+ blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
+ if (!dev->bid_type)
+ continue;
+ if ((ret = save_dev(dev, file)) < 0)
+ break;
+ }
+
+ if (ret >= 0) {
+ cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
+ ret = 1;
+ }
+
+ fclose(file);
+ if (opened != filename) {
+ if (ret < 0) {
+ unlink(opened);
+ DBG(DEBUG_SAVE,
+ printf("unlinked temp cache %s\n", opened));
+ } else {
+ char *backup;
+
+ backup = malloc(strlen(filename) + 5);
+ if (backup) {
+ sprintf(backup, "%s.old", filename);
+ unlink(backup);
+ link(filename, backup);
+ free(backup);
+ }
+ rename(opened, filename);
+ DBG(DEBUG_SAVE,
+ printf("moved temp cache %s\n", opened));
+ }
+ }
+
+errout:
+ free(tmp);
+ return ret;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv)
+{
+ blkid_cache cache = NULL;
+ int ret;
+
+ blkid_init_debug(DEBUG_ALL);
+ if (argc > 2) {
+ fprintf(stderr, "Usage: %s [filename]\n"
+ "Test loading/saving a cache (filename)\n", argv[0]);
+ exit(1);
+ }
+
+ if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+ if ((ret = blkid_probe_all(cache)) < 0) {
+ fprintf(stderr, "error (%d) probing devices\n", ret);
+ exit(1);
+ }
+ cache->bic_filename = blkid_strdup(argv[1]);
+
+ if ((ret = blkid_flush_cache(cache)) < 0) {
+ fprintf(stderr, "error (%d) saving cache\n", ret);
+ exit(1);
+ }
+
+ blkid_put_cache(cache);
+
+ return ret;
+}
+#endif
diff --git a/shlibs/blkid/src/tag.c b/shlibs/blkid/src/tag.c
new file mode 100644
index 000000000..0dbe1ff5a
--- /dev/null
+++ b/shlibs/blkid/src/tag.c
@@ -0,0 +1,474 @@
+/*
+ * tag.c - allocation/initialization/free routines for tag structs
+ *
+ * Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ * %End-Header%
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "blkidP.h"
+
+static blkid_tag blkid_new_tag(void)
+{
+ blkid_tag tag;
+
+ if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag))))
+ return NULL;
+
+ INIT_LIST_HEAD(&tag->bit_tags);
+ INIT_LIST_HEAD(&tag->bit_names);
+
+ return tag;
+}
+
+#ifdef CONFIG_BLKID_DEBUG
+void blkid_debug_dump_tag(blkid_tag tag)
+{
+ if (!tag) {
+ printf(" tag: NULL\n");
+ return;
+ }
+
+ printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
+}
+#endif
+
+void blkid_free_tag(blkid_tag tag)
+{
+ if (!tag)
+ return;
+
+ DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name,
+ tag->bit_val ? tag->bit_val : "(NULL)"));
+ DBG(DEBUG_TAG, blkid_debug_dump_tag(tag));
+
+ list_del(&tag->bit_tags); /* list of tags for this device */
+ list_del(&tag->bit_names); /* list of tags with this type */
+
+ free(tag->bit_name);
+ free(tag->bit_val);
+
+ free(tag);
+}
+
+/*
+ * Find the desired tag on a device. If value is NULL, then the
+ * first such tag is returned, otherwise return only exact tag if found.
+ */
+blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type)
+{
+ struct list_head *p;
+
+ if (!dev || !type)
+ return NULL;
+
+ list_for_each(p, &dev->bid_tags) {
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
+ bit_tags);
+
+ if (!strcmp(tmp->bit_name, type))
+ return tmp;
+ }
+ return NULL;
+}
+
+extern int blkid_dev_has_tag(blkid_dev dev, const char *type,
+ const char *value)
+{
+ blkid_tag tag;
+
+ if (!dev || !type)
+ return -1;
+
+ tag = blkid_find_tag_dev(dev, type);
+ if (!value)
+ return (tag != NULL);
+ if (!tag || strcmp(tag->bit_val, value))
+ return 0;
+ return 1;
+}
+
+/*
+ * Find the desired tag type in the cache.
+ * We return the head tag for this tag type.
+ */
+static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
+{
+ blkid_tag head = NULL, tmp;
+ struct list_head *p;
+
+ if (!cache || !type)
+ return NULL;
+
+ list_for_each(p, &cache->bic_tags) {
+ tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
+ if (!strcmp(tmp->bit_name, type)) {
+ DBG(DEBUG_TAG,
+ printf(" found cache tag head %s\n", type));
+ head = tmp;
+ break;
+ }
+ }
+ return head;
+}
+
+/*
+ * Set a tag on an existing device.
+ *
+ * If value is NULL, then delete the tagsfrom the device.
+ */
+int blkid_set_tag(blkid_dev dev, const char *name,
+ const char *value, const int vlength)
+{
+ blkid_tag t = 0, head = 0;
+ char *val = 0;
+ char **dev_var = 0;
+
+ if (!dev || !name)
+ return -BLKID_ERR_PARAM;
+
+ if (!(val = blkid_strndup(value, vlength)) && value)
+ return -BLKID_ERR_MEM;
+
+ /*
+ * Certain common tags are linked directly to the device struct
+ * We need to know what they are before we do anything else because
+ * the function name parameter might get freed later on.
+ */
+ if (!strcmp(name, "TYPE"))
+ dev_var = &dev->bid_type;
+ else if (!strcmp(name, "LABEL"))
+ dev_var = &dev->bid_label;
+ else if (!strcmp(name, "UUID"))
+ dev_var = &dev->bid_uuid;
+
+ t = blkid_find_tag_dev(dev, name);
+ if (!value) {
+ if (t)
+ blkid_free_tag(t);
+ } else if (t) {
+ if (!strcmp(t->bit_val, val)) {
+ /* Same thing, exit */
+ free(val);
+ return 0;
+ }
+ free(t->bit_val);
+ t->bit_val = val;
+ } else {
+ /* Existing tag not present, add to device */
+ if (!(t = blkid_new_tag()))
+ goto errout;
+ t->bit_name = blkid_strdup(name);
+ t->bit_val = val;
+ t->bit_dev = dev;
+
+ list_add_tail(&t->bit_tags, &dev->bid_tags);
+
+ if (dev->bid_cache) {
+ head = blkid_find_head_cache(dev->bid_cache,
+ t->bit_name);
+ if (!head) {
+ head = blkid_new_tag();
+ if (!head)
+ goto errout;
+
+ DBG(DEBUG_TAG,
+ printf(" creating new cache tag head %s\n", name));
+ head->bit_name = blkid_strdup(name);
+ if (!head->bit_name)
+ goto errout;
+ list_add_tail(&head->bit_tags,
+ &dev->bid_cache->bic_tags);
+ }
+ list_add_tail(&t->bit_names, &head->bit_names);
+ }
+ }
+
+ /* Link common tags directly to the device struct */
+ if (dev_var)
+ *dev_var = val;
+
+ if (dev->bid_cache)
+ dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+ return 0;
+
+errout:
+ if (t)
+ blkid_free_tag(t);
+ else
+ free(val);
+ if (head)
+ blkid_free_tag(head);
+ return -BLKID_ERR_MEM;
+}
+
+
+/*
+ * Parse a "NAME=value" string. This is slightly different than
+ * parse_token, because that will end an unquoted value at a space, while
+ * this will assume that an unquoted value is the rest of the token (e.g.
+ * if we are passed an already quoted string from the command-line we don't
+ * have to both quote and escape quote so that the quotes make it to
+ * us).
+ *
+ * Returns 0 on success, and -1 on failure.
+ */
+int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
+{
+ char *name, *value, *cp;
+
+ DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token));
+
+ if (!token || !(cp = strchr(token, '=')))
+ return -1;
+
+ name = blkid_strdup(token);
+ if (!name)
+ return -1;
+ value = name + (cp - token);
+ *value++ = '\0';
+ if (*value == '"' || *value == '\'') {
+ char c = *value++;
+ if (!(cp = strrchr(value, c)))
+ goto errout; /* missing closing quote */
+ *cp = '\0';
+ }
+ value = blkid_strdup(value);
+ if (!value)
+ goto errout;
+
+ *ret_type = name;
+ *ret_val = value;
+
+ return 0;
+
+errout:
+ free(name);
+ return -1;
+}
+
+/*
+ * Tag iteration routines for the public libblkid interface.
+ *
+ * These routines do not expose the list.h implementation, which are a
+ * contamination of the namespace, and which force us to reveal far, far
+ * too much of our internal implemenation. I'm not convinced I want
+ * to keep list.h in the long term, anyway. It's fine for kernel
+ * programming, but performance is not the #1 priority for this
+ * library, and I really don't like the tradeoff of type-safety for
+ * performance for this application. [tytso:20030125.2007EST]
+ */
+
+/*
+ * This series of functions iterate over all tags in a device
+ */
+#define TAG_ITERATE_MAGIC 0x01a5284c
+
+struct blkid_struct_tag_iterate {
+ int magic;
+ blkid_dev dev;
+ struct list_head *p;
+};
+
+extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev)
+{
+ blkid_tag_iterate iter;
+
+ iter = malloc(sizeof(struct blkid_struct_tag_iterate));
+ if (iter) {
+ iter->magic = TAG_ITERATE_MAGIC;
+ iter->dev = dev;
+ iter->p = dev->bid_tags.next;
+ }
+ return (iter);
+}
+
+/*
+ * Return 0 on success, -1 on error
+ */
+extern int blkid_tag_next(blkid_tag_iterate iter,
+ const char **type, const char **value)
+{
+ blkid_tag tag;
+
+ *type = 0;
+ *value = 0;
+ if (!iter || iter->magic != TAG_ITERATE_MAGIC ||
+ iter->p == &iter->dev->bid_tags)
+ return -1;
+ tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags);
+ *type = tag->bit_name;
+ *value = tag->bit_val;
+ iter->p = iter->p->next;
+ return 0;
+}
+
+extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
+{
+ if (!iter || iter->magic != TAG_ITERATE_MAGIC)
+ return;
+ iter->magic = 0;
+ free(iter);
+}
+
+/*
+ * This function returns a device which matches a particular
+ * type/value pair. If there is more than one device that matches the
+ * search specification, it returns the one with the highest priority
+ * value. This allows us to give preference to EVMS or LVM devices.
+ */
+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
+ const char *type,
+ const char *value)
+{
+ blkid_tag head;
+ blkid_dev dev;
+ int pri;
+ struct list_head *p;
+ int probe_new = 0;
+
+ if (!cache || !type || !value)
+ return NULL;
+
+ blkid_read_cache(cache);
+
+ DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value));
+
+try_again:
+ pri = -1;
+ dev = 0;
+ head = blkid_find_head_cache(cache, type);
+
+ if (head) {
+ list_for_each(p, &head->bit_names) {
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
+ bit_names);
+
+ if (!strcmp(tmp->bit_val, value) &&
+ (tmp->bit_dev->bid_pri > pri) &&
+ !access(tmp->bit_dev->bid_name, F_OK)) {
+ dev = tmp->bit_dev;
+ pri = dev->bid_pri;
+ }
+ }
+ }
+ if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
+ dev = blkid_verify(cache, dev);
+ if (!dev || (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)))
+ goto try_again;
+ }
+
+ if (!dev && !probe_new) {
+ if (blkid_probe_all_new(cache) < 0)
+ return NULL;
+ probe_new++;
+ goto try_again;
+ }
+
+ if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
+ if (blkid_probe_all(cache) < 0)
+ return NULL;
+ goto try_again;
+ }
+ return dev;
+}
+
+#ifdef TEST_PROGRAM
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern char *optarg;
+extern int optind;
+#endif
+
+void usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device "
+ "[type value]\n",
+ prog);
+ fprintf(stderr, "\tList all tags for a device and exit\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ blkid_tag_iterate iter;
+ blkid_cache cache = NULL;
+ blkid_dev dev;
+ int c, ret, found;
+ int flags = BLKID_DEV_FIND;
+ char *tmp;
+ char *file = NULL;
+ char *devname = NULL;
+ char *search_type = NULL;
+ char *search_value = NULL;
+ const char *type, *value;
+
+ while ((c = getopt (argc, argv, "m:f:")) != EOF)
+ switch (c) {
+ case 'f':
+ file = optarg;
+ break;
+ case 'm':
+ {
+ int mask = strtoul (optarg, &tmp, 0);
+ if (*tmp) {
+ fprintf(stderr, "Invalid debug mask: %s\n",
+ optarg);
+ exit(1);
+ }
+ blkid_init_debug(mask);
+ break;
+ }
+ case '?':
+ usage(argv[0]);
+ }
+ if (argc > optind)
+ devname = argv[optind++];
+ if (argc > optind)
+ search_type = argv[optind++];
+ if (argc > optind)
+ search_value = argv[optind++];
+ if (!devname || (argc != optind))
+ usage(argv[0]);
+
+ if ((ret = blkid_get_cache(&cache, file)) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+
+ dev = blkid_get_dev(cache, devname, flags);
+ if (!dev) {
+ fprintf(stderr, "%s: Can not find device in blkid cache\n",
+ devname);
+ exit(1);
+ }
+ if (search_type) {
+ found = blkid_dev_has_tag(dev, search_type, search_value);
+ printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev),
+ search_type, search_value ? search_value : "NULL",
+ found ? "FOUND" : "NOT FOUND");
+ return(!found);
+ }
+ printf("Device %s...\n", blkid_dev_devname(dev));
+
+ iter = blkid_tag_iterate_begin(dev);
+ while (blkid_tag_next(iter, &type, &value) == 0) {
+ printf("\tTag %s has value %s\n", type, value);
+ }
+ blkid_tag_iterate_end(iter);
+
+ blkid_put_cache(cache);
+ return (0);
+}
+#endif
diff --git a/shlibs/blkid/src/tst_types.c b/shlibs/blkid/src/tst_types.c
new file mode 100644
index 000000000..ecbc03217
--- /dev/null
+++ b/shlibs/blkid/src/tst_types.c
@@ -0,0 +1,63 @@
+/*
+ * This testing program makes sure the stdint.h header file
+ *
+ * Copyright (C) 2006 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ if (sizeof(uint8_t) != 1) {
+ printf("Sizeof(uint8_t) is %d should be 1\n",
+ (int)sizeof(uint8_t));
+ exit(1);
+ }
+ if (sizeof(int8_t) != 1) {
+ printf("Sizeof(int8_t) is %d should be 1\n",
+ (int)sizeof(int8_t));
+ exit(1);
+ }
+ if (sizeof(uint16_t) != 2) {
+ printf("Sizeof(uint16_t) is %d should be 2\n",
+ (int)sizeof(uint16_t));
+ exit(1);
+ }
+ if (sizeof(int16_t) != 2) {
+ printf("Sizeof(int16_t) is %d should be 2\n",
+ (int)sizeof(int16_t));
+ exit(1);
+ }
+ if (sizeof(uint32_t) != 4) {
+ printf("Sizeof(uint32_t) is %d should be 4\n",
+ (int)sizeof(uint32_t));
+ exit(1);
+ }
+ if (sizeof(int32_t) != 4) {
+ printf("Sizeof(int32_t) is %d should be 4\n",
+ (int)sizeof(int32_t));
+ exit(1);
+ }
+ if (sizeof(uint64_t) != 8) {
+ printf("Sizeof(uint64_t) is %d should be 8\n",
+ (int)sizeof(uint64_t));
+ exit(1);
+ }
+ if (sizeof(int64_t) != 8) {
+ printf("Sizeof(int64_t) is %d should be 8\n",
+ (int)sizeof(int64_t));
+ exit(1);
+ }
+ printf("The stdint.h types are correct.\n");
+ exit(0);
+}
+
diff --git a/shlibs/blkid/src/verify.c b/shlibs/blkid/src/verify.c
new file mode 100644
index 000000000..40ab4c672
--- /dev/null
+++ b/shlibs/blkid/src/verify.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "blkidP.h"
+
+static void blkid_probe_to_tags(blkid_probe pr, blkid_dev dev)
+{
+ const char *data;
+ const char *name;
+ int nvals, n;
+ size_t len;
+
+ nvals = blkid_probe_numof_values(pr);
+
+ for (n = 0; n < nvals; n++) {
+ if (blkid_probe_get_value(pr, n, &name, &data, &len) == 0)
+ blkid_set_tag(dev, name, data, len);
+ }
+}
+
+/*
+ * Verify that the data in dev is consistent with what is on the actual
+ * block device (using the devname field only). Normally this will be
+ * called when finding items in the cache, but for long running processes
+ * is also desirable to revalidate an item before use.
+ *
+ * If we are unable to revalidate the data, we return the old data and
+ * do not set the BLKID_BID_FL_VERIFIED flag on it.
+ */
+blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
+{
+ struct stat st;
+ time_t diff, now;
+ char *fltr[2];
+ int fd;
+
+ if (!dev)
+ return NULL;
+
+ now = time(0);
+ diff = now - dev->bid_time;
+
+ if (stat(dev->bid_name, &st) < 0) {
+ DBG(DEBUG_PROBE,
+ printf("blkid_verify: error %s (%d) while "
+ "trying to stat %s\n", strerror(errno), errno,
+ dev->bid_name));
+ open_err:
+ if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
+ /* We don't have read permission, just return cache data. */
+ DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
+ dev->bid_name));
+ return dev;
+ }
+ blkid_free_dev(dev);
+ return NULL;
+ }
+
+ if ((now >= dev->bid_time) &&
+ (st.st_mtime <= dev->bid_time) &&
+ ((diff < BLKID_PROBE_MIN) ||
+ (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
+ diff < BLKID_PROBE_INTERVAL)))
+ return dev;
+
+ DBG(DEBUG_PROBE,
+ printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
+ "time since last check %lu)\n",
+ dev->bid_name, (unsigned long)dev->bid_time,
+ (unsigned long)st.st_mtime, (unsigned long)diff));
+
+
+ if (!cache->probe)
+ cache->probe = blkid_new_probe();
+
+ fd = open(dev->bid_name, O_RDONLY);
+ if (fd < 0) {
+ DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while "
+ "opening %s\n", strerror(errno), errno,
+ dev->bid_name));
+ goto open_err;
+ }
+
+ if (blkid_probe_set_device(cache->probe, fd, 0, 0)) {
+ /* failed to read the device */
+ close(fd);
+ blkid_free_dev(dev);
+ return NULL;
+ }
+
+ blkid_probe_set_request(cache->probe,
+ BLKID_PROBREQ_LABEL | BLKID_PROBREQ_UUID |
+ BLKID_PROBREQ_TYPE | BLKID_PROBREQ_SECTYPE);
+
+ /*
+ * If we already know the type, then try that first.
+ */
+ if (dev->bid_type) {
+ blkid_tag_iterate iter;
+ const char *type, *value;
+
+ fltr[0] = dev->bid_type;
+ fltr[1] = NULL;
+
+ blkid_probe_filter_types(cache->probe,
+ BLKID_FLTR_ONLYIN, fltr);
+
+ if (!blkid_do_probe(cache->probe))
+ goto found_type;
+ blkid_probe_invert_filter(cache->probe);
+
+ /*
+ * Zap the device filesystem information and try again
+ */
+ DBG(DEBUG_PROBE,
+ printf("previous fs type %s not valid, "
+ "trying full probe\n", dev->bid_type));
+ iter = blkid_tag_iterate_begin(dev);
+ while (blkid_tag_next(iter, &type, &value) == 0)
+ blkid_set_tag(dev, type, 0, 0);
+ blkid_tag_iterate_end(iter);
+ }
+
+ /*
+ * Probe for all types.
+ */
+ if (blkid_do_safeprobe(cache->probe)) {
+ /* found nothing or error */
+ blkid_free_dev(dev);
+ dev = NULL;
+ }
+
+found_type:
+ if (dev) {
+ dev->bid_devno = st.st_rdev;
+ dev->bid_time = time(0);
+ dev->bid_flags |= BLKID_BID_FL_VERIFIED;
+ cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+
+ blkid_probe_to_tags(cache->probe, dev);
+
+ DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
+ dev->bid_name, (long long)st.st_rdev, dev->bid_type));
+ }
+
+ blkid_reset_probe(cache->probe);
+ blkid_probe_reset_filter(cache->probe);
+ close(fd);
+ return dev;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv)
+{
+ blkid_dev dev;
+ blkid_cache cache;
+ int ret;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s device\n"
+ "Probe a single device to determine type\n", argv[0]);
+ exit(1);
+ }
+ if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+ fprintf(stderr, "%s: error creating cache (%d)\n",
+ argv[0], ret);
+ exit(1);
+ }
+ dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
+ if (!dev) {
+ printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
+ return (1);
+ }
+ printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)");
+ if (dev->bid_label)
+ printf("LABEL='%s'\n", dev->bid_label);
+ if (dev->bid_uuid)
+ printf("UUID='%s'\n", dev->bid_uuid);
+
+ blkid_free_dev(dev);
+ return (0);
+}
+#endif
diff --git a/shlibs/blkid/src/version.c b/shlibs/blkid/src/version.c
new file mode 100644
index 000000000..838af1146
--- /dev/null
+++ b/shlibs/blkid/src/version.c
@@ -0,0 +1,56 @@
+/*
+ * version.c --- Return the version of the blkid library
+ *
+ * Copyright (C) 2004 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "blkid.h"
+
+/* LIBBLKID_* defined in the global config.h */
+static const char *lib_version = LIBBLKID_VERSION; /* release version */
+static const char *lib_date = LIBBLKID_DATE;
+
+int blkid_parse_version_string(const char *ver_string)
+{
+ const char *cp;
+ int version = 0;
+
+ for (cp = ver_string; *cp; cp++) {
+ if (*cp == '.')
+ continue;
+ if (!isdigit(*cp))
+ break;
+ version = (version * 10) + (*cp - '0');
+ }
+ return version;
+}
+
+/**
+ * blkid_get_library_version:
+ * @ver_string: returns relese version (!= SONAME version)
+ * @date_string: returns date
+ *
+ * Returns release version code.
+ */
+int blkid_get_library_version(const char **ver_string,
+ const char **date_string)
+{
+ if (ver_string)
+ *ver_string = lib_version;
+ if (date_string)
+ *date_string = lib_date;
+
+ return blkid_parse_version_string(lib_version);
+}