linux-blkid (empty) → 0.1.0.0
raw patch · 8 files changed
+2110/−0 lines, 8 filesdep +basedep +transformerssetup-changed
Dependencies added: base, transformers
Files
- LICENSE +502/−0
- Setup.hs +4/−0
- System/Linux/Blkid.hs +12/−0
- System/Linux/Blkid/Cache.hsc +367/−0
- System/Linux/Blkid/Evaluate.hsc +110/−0
- System/Linux/Blkid/Probe.hsc +1003/−0
- System/Linux/Blkid/Utils.hsc +86/−0
- linux-blkid.cabal +26/−0
+ LICENSE view
@@ -0,0 +1,502 @@+ GNU LESSER GENERAL PUBLIC LICENSE+ Version 2.1, February 1999++ Copyright (C) 1991, 1999 Free Software Foundation, Inc.+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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.++ 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.++ 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.++ 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.++ 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.++ 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.++ 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.++ 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++ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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!
+ Setup.hs view
@@ -0,0 +1,4 @@+import Distribution.Simple++main :: IO ()+main = defaultMain
+ System/Linux/Blkid.hs view
@@ -0,0 +1,12 @@+-- | Bindings to the Linux @libblkid@ library.+module System.Linux.Blkid+ ( module System.Linux.Blkid.Cache+ , module System.Linux.Blkid.Evaluate+ , module System.Linux.Blkid.Probe+ , module System.Linux.Blkid.Utils+ ) where++import System.Linux.Blkid.Cache+import System.Linux.Blkid.Evaluate+import System.Linux.Blkid.Probe+import System.Linux.Blkid.Utils
+ System/Linux/Blkid/Cache.hsc view
@@ -0,0 +1,367 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ForeignFunctionInterface #-}++-- | Basic routines to work with @libblkid@ cache.+module System.Linux.Blkid.Cache+ ( CacheT+ , withCache+ , gcCache+ , probeAll+ , probeAllRemovable+ , probeAllNew+ , verify+ , evaluateTagUsingCache+ , evaluateSpecUsingCache+ , Device+ , getDevices+ , getDevicesWithTag+ , deviceGetTags+ , deviceHasTag+ , findDeviceWithTag+ , DevFlags(..)+ , getDevice+ , getDevname+ , getTagValue+ ) where++import Control.Exception (bracket)+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import Control.Monad.Trans.State+import Foreign+import Foreign.C+import System.Linux.Blkid.Evaluate (Tag(..))++#include <blkid/blkid.h>++foreign import ccall "stdlib.h free"+ c_free :: Ptr a -> IO ()++type BlkidCache = Ptr BlkidStructCache++data BlkidStructCache++-- | An operation using the @blkid.tab@ cache file, and returning a+-- value of type @a@. The computation is not performed until+-- @'withCache'@ is called.+newtype CacheT m a = CacheT {runCacheT :: StateT BlkidCache m a}++instance MonadTrans CacheT where+ lift = CacheT . lift++instance Functor f => Functor (CacheT f) where+ fmap f = CacheT . (fmap f) . runCacheT++instance Monad m => Monad (CacheT m) where+ return = CacheT . return+ (CacheT m) >>= f = CacheT (m >>= runCacheT . f)+ fail = CacheT . fail+++instance MonadIO m => MonadIO (CacheT m) where+ liftIO = CacheT . liftIO++-- | Run a @'CacheT'@ operation using the given cache file, or the+-- default (@\/run\/blkid\/blkid.tab@) if @'Nothing'@ is passed. After+-- completing the computation, the new cache is written to the file if+-- the user has sufficent privileges.+withCache :: MonadIO m => Maybe FilePath -> CacheT m a -> m a+withCache mpath (CacheT (StateT f)) =+ do c <- liftIO $+ maybeWith withCString mpath $ \cstr ->+ alloca $ \p ->+ do e <- get_cache p cstr+ if e < 0+ then fail ("blkid_get_cache returned " ++ show e)+ else peek p+ (a,c') <- f c+ liftIO $ put_cache c'+ return a++--getDevices :: MonadIO m => CacheT m [Device]++--getDevice :: MonadIO m => String -> DevFlags -> CacheT m (Maybe Device)++type BlkidDev = Ptr Device++-- | A device as represented in the @blkid.tab@ cache file.+data Device = Device (ForeignPtr Device) String++withDevice :: Device -> (BlkidDev -> IO a) -> IO a+withDevice (Device p _) = withForeignPtr p++toDevice :: BlkidDev -> IO Device+toDevice p = do fp <- newForeignPtr_ p+ name <- dev_devname p >>= peekCString+ return (Device fp name)++instance Show Device where+ show (Device _ name) = name++-- | Removes garbage (non-existing devices) from the cache.+gcCache :: MonadIO m => CacheT m ()+gcCache = CacheT $ StateT $ \c -> do liftIO $ gc_cache c+ return ((),c)++-- | Probes all block devices.+probeAll :: MonadIO m => CacheT m ()+probeAll =+ CacheT $ StateT $ \c ->+ do liftIO $ throwIfNeg_ (\e -> "blkid_probe_all returned " ++ show e)+ (probe_all c)+ return ((),c)++-- | The libblkid probing is based on devices from+-- @\/proc\/partitions@ by default. This file usually does not contain+-- removable devices (e.g. CDROMs) and this kind of devices are+-- invisible for libblkid.+--+-- This function adds removable block devices to cache (probing is+-- based on information from the @\/sys@ directory). Don't forget that+-- removable devices (floppies, CDROMs, ...) could be pretty+-- slow. It's very bad idea to call this function by default.+--+-- Note that devices which were detected by this function won't be+-- written to @blkid.tab@ cache file.+probeAllRemovable :: MonadIO m => CacheT m ()+probeAllRemovable =+ CacheT $ StateT $ \c ->+ do liftIO $ throwIfNeg_ (\e -> "blkid_probe_all_removable returned " +++ show e) (probe_all_removable c)+ return ((),c)++-- | Probes all new block devices.+probeAllNew :: MonadIO m => CacheT m ()+probeAllNew =+ CacheT $ StateT $ \c ->+ do liftIO $ throwIfNeg_ (\e -> "blkid_probe_all_new returned " +++ show e) (probe_all_new c)+ return ((),c)++-- | Verify that the data in @'Device'@ 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.+verify :: MonadIO m => Device -> CacheT m Device+verify dev =+ CacheT $ StateT $ \c ->+ do dev' <- liftIO $ withDevice dev $ \d -> blkid_verify c d >>= toDevice+ return (dev',c)++-- | Get the list of tags and values for the given @'Device'@.+deviceGetTags :: MonadIO m => Device -> m [(String, String)]+deviceGetTags dev =+ liftIO $ withDevice dev $ \d -> bracket (begin d) tag_iterate_end getTag+ where begin ptr = do it <- tag_iterate_begin ptr+ if it == nullPtr+ then fail "blkid_tag_iterate_begin returned NULL"+ else return it+ getTag iter = alloca $ \t ->+ alloca $ \v ->+ do e <- tag_next iter t v+ if e < 0+ then return []+ else do typ <- peek t >>= peekCString+ val <- peek v >>= peekCString+ xs <- getTag iter+ return ((typ,val):xs)++-- | Check if @'Device'@ has the give tag and value.+deviceHasTag :: MonadIO m => Device -> String -> String -> m Bool+deviceHasTag dev typ val =+ liftIO $ withDevice dev $ \d ->+ withCString typ $ \t ->+ withCString val $ \v ->+ dev_has_tag d t v >>= return . toBool++-- | Find a @'Device'@ in cache matching the given tag and value.+findDeviceWithTag :: MonadIO m => String -> String -> CacheT m (Maybe Device)+findDeviceWithTag typ val =+ CacheT $ StateT $ \c ->+ do mdev <- liftIO $ withCString typ $ \t ->+ withCString val $ \v ->+ find_dev_with_tag c t v >>= maybePeek toDevice+ return (mdev,c)++-- | Flags for @'getDevice'@.+data DevFlags = Find+ | Create+ | Verify+ | Normal+ deriving (Eq, Show)++fromDevFlags :: Num a => DevFlags -> a+fromDevFlags Find = #{const BLKID_DEV_FIND}+fromDevFlags Create = #{const BLKID_DEV_CREATE}+fromDevFlags Verify = #{const BLKID_DEV_VERIFY}+fromDevFlags Normal = #{const BLKID_DEV_NORMAL}++-- | Get the device in cache with the given name.+getDevice :: MonadIO m => String -> DevFlags -> CacheT m (Maybe Device)+getDevice nam fl =+ CacheT $ StateT $ \c ->+ do mdev <- liftIO $ withCString nam $ \n ->+ get_dev c n (fromDevFlags fl) >>= maybePeek toDevice+ return (mdev,c)++-- | Get the device name of the device in cache matching the given tag+-- and value.+getDevname :: MonadIO m => String -> String -> CacheT m (Maybe String)+getDevname tok val =+ CacheT $ StateT $ \c ->+ do mstr <- liftIO $ withCString tok $ \t ->+ withCString val $ \v ->+ bracket (get_devname c t v) c_free (maybePeek peekCString)+ return (mstr,c)++-- | Get the value of a tag given the tag and device name.+getTagValue :: MonadIO m => String -> String -> CacheT m (Maybe String)+getTagValue tok nam =+ CacheT $ StateT $ \c ->+ do mstr <- liftIO $ withCString tok $ \t ->+ withCString nam $ \n ->+ bracket (get_tag_value c t n) c_free (maybePeek peekCString)+ return (mstr,c)++devIterate :: MonadIO m => Maybe String -> String -> CacheT m [Device]+devIterate mtok val =+ CacheT $ StateT $ \c ->+ do devs <- liftIO $ bracket (getIter c) dev_iterate_end getDev+ return (devs,c)+ where getIter p = do it <- dev_iterate_begin p+ if it == nullPtr+ then fail "blkid_dev_iterate_begin returned NULL" + else case mtok of+ Nothing -> return it+ Just tok ->+ withCString tok $ \t ->+ withCString val $ \v ->+ do throwIfNeg_ (\e -> "blkid_dev_set_search returned " ++ show e)+ (dev_set_search it t v)+ return it+ getDev it = alloca $ \pd -> do e <- dev_next it pd+ if e < 0+ then return []+ else do d <- peek pd >>= toDevice+ ds <- getDev it+ return (d:ds)++-- | Get the list of devices in cache.+getDevices :: MonadIO m => CacheT m [Device]+getDevices = devIterate Nothing []++-- | Get the list of devices in cache matching the given tag and value.+getDevicesWithTag :: MonadIO m => String -> String -> CacheT m [Device]+getDevicesWithTag tok val = devIterate (Just tok) val++-- | Get the partition or filesystem device with the given @'Tag'@,+-- using the cache file.+evaluateTagUsingCache :: MonadIO m => Tag -> CacheT m (Maybe String)+evaluateTagUsingCache (Label str) = evalTag "LABEL" str+evaluateTagUsingCache (PartLabel str) = evalTag "PARTLABEL" str+evaluateTagUsingCache (UUID str) = evalTag "UUID" str+evaluateTagUsingCache (PartUUID str) = evalTag "PARTUUID" str++evalTag :: MonadIO m => String -> String -> CacheT m (Maybe String)+evalTag tok val =+ CacheT $ StateT $ \c ->+ liftIO $ alloca $ \p ->+ do poke p c+ mstr <- bracket (withCString tok $ \t ->+ withCString val $ \v ->+ evaluate_tag t v p)+ c_free+ (maybePeek peekCString)+ c' <- peek p+ return (mstr,c')++-- | Get the desired partition or filesystem device, using the cache+-- file.+evaluateSpecUsingCache :: MonadIO m => String -> CacheT m (Maybe String)+evaluateSpecUsingCache spec =+ CacheT $ StateT $ \c ->+ liftIO $ alloca $ \p ->+ do poke p c+ mstr <- bracket (withCString spec $ \s -> evaluate_spec s p)+ c_free+ (maybePeek peekCString)+ c' <- peek p+ return (mstr,c')++type BlkidDevIterate = Ptr DevIterate++data DevIterate++type BlkidTagIterate = Ptr TagIterate++data TagIterate++foreign import ccall "blkid_put_cache" put_cache :: BlkidCache -> IO ()++foreign import ccall "blkid_get_cache" get_cache :: Ptr BlkidCache+ -> CString+ -> IO CInt++foreign import ccall "blkid_gc_cache" gc_cache :: BlkidCache -> IO ()++foreign import ccall "blkid_dev_devname" dev_devname :: BlkidDev -> IO CString++foreign import ccall "blkid_dev_iterate_begin"+ dev_iterate_begin :: BlkidCache -> IO BlkidDevIterate++foreign import ccall "blkid_dev_set_search" dev_set_search :: BlkidDevIterate+ -> CString+ -> CString+ -> IO CInt++foreign import ccall "blkid_dev_next" dev_next :: BlkidDevIterate+ -> Ptr BlkidDev+ -> IO CInt++foreign import ccall "blkid_dev_iterate_end" dev_iterate_end :: BlkidDevIterate+ -> IO ()++foreign import ccall "blkid_probe_all" probe_all :: BlkidCache -> IO CInt++foreign import ccall "blkid_probe_all_new" probe_all_new :: BlkidCache+ -> IO CInt++foreign import ccall "blkid_probe_all_removable"+ probe_all_removable :: BlkidCache -> IO CInt++foreign import ccall "blkid_get_dev"+ get_dev :: BlkidCache -> CString -> CInt -> IO BlkidDev++foreign import ccall "blkid_verify"+ blkid_verify :: BlkidCache -> BlkidDev -> IO BlkidDev++foreign import ccall "blkid_get_tag_value"+ get_tag_value :: BlkidCache -> CString -> CString -> IO CString++foreign import ccall "blkid_get_devname"+ get_devname :: BlkidCache -> CString -> CString -> IO CString++foreign import ccall "blkid_tag_iterate_begin"+ tag_iterate_begin :: BlkidDev -> IO BlkidTagIterate++foreign import ccall "blkid_tag_next"+ tag_next :: BlkidTagIterate -> Ptr CString -> Ptr CString -> IO CInt++foreign import ccall "blkid_tag_iterate_end"+ tag_iterate_end :: BlkidTagIterate -> IO ()++foreign import ccall "blkid_dev_has_tag"+ dev_has_tag :: BlkidDev -> CString -> CString -> IO CInt++foreign import ccall "blkid_find_dev_with_tag"+ find_dev_with_tag :: BlkidCache -> CString -> CString -> IO BlkidDev++foreign import ccall "blkid_evaluate_tag" evaluate_tag :: CString+ -> CString+ -> Ptr BlkidCache+ -> IO CString++foreign import ccall "blkid_evaluate_spec" evaluate_spec :: CString+ -> Ptr BlkidCache+ -> IO CString
+ System/Linux/Blkid/Evaluate.hsc view
@@ -0,0 +1,110 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ForeignFunctionInterface #-}++-- | Tags and Spec evaluation.+module System.Linux.Blkid.Evaluate+ ( Tag(..)+ , evaluateTag+-- , evaluateTagUsingCache+ , evaluateSpec+-- , evaluateSpecUsingCache+ ) where++import Control.Exception (bracket)+import Control.Monad.IO.Class+import Foreign+import Foreign.C++#include <blkid/blkid.h>++foreign import ccall "stdlib.h free"+ c_free :: Ptr a -> IO ()++type BlkidCache = Ptr BlkidStructCache++data BlkidStructCache++-- | Partition or filesystem tag.+data Tag = Label String+ | PartLabel String+ | UUID String+ | PartUUID String+ deriving (Eq, Show)++{-+evalTag :: MonadIO m => String -> String -> BlkidCache -> m (Maybe String)+evalTag tok val cac =+ liftIO $ bracket $ + (withCString tok $ \t ->+ withCString val $ \v ->+ with cac \c ->+ evaluate_tag t v c)+ c_free+ (maybePeek peekCString)+-}++-- | Get the partition or filesystem device with the given @'Tag'@.+--+-- Example:+--+-- >>> evaluateTag (PartLabel "EFI System Partition")+-- Just "/dev/sda1"+evaluateTag :: MonadIO m => Tag -> m (Maybe String)+evaluateTag (Label str) = liftIO $ evalTag "LABEL" str+evaluateTag (PartLabel str) = liftIO $ evalTag "PARTLABEL" str+evaluateTag (UUID str) = liftIO $ evalTag "UUID" str+evaluateTag (PartUUID str) = liftIO $ evalTag "PARTUUID" str++evalTag :: String -> String -> IO (Maybe String)+evalTag tok val =+ bracket (withCString tok $ \t ->+ withCString val $ \v ->+ evaluate_tag t v nullPtr)+ c_free+ (maybePeek peekCString)+{-+evaluateTagUsingCache :: MonadIO m => String -> String -> CacheT m (Maybe String)+evaluateTagUsingCache tok val =+ CacheT $ StateT $ \c ->+ do mstr <- evalTag tok val c+ return (mstr,c)++evalSpec :: MonadIO m => String -> Ptr BlkidCache -> m (Maybe String)+evalSpec spec c =+ liftIO $ bracket+ (withCString spec $ \s -> evaluate_spec s c)+ c_free+ (maybePeek peekCString)+-}++-- | Get the desired partition or filesystem device.+--+-- Examples:+--+-- >>> evaluateSpec "LABEL=EFI"+-- Just "/dev/sda1"+--+-- >>> evaluateSpec "/dev/disk/by-label/EFI"+-- Just "/dev/sda1"+evaluateSpec :: MonadIO m => String -> m (Maybe String)+evaluateSpec spec =+ liftIO $ bracket+ (withCString spec $ \s -> evaluate_spec s nullPtr)+ c_free+ (maybePeek peekCString)++{-+evaluateSpecUsingCache :: MonadIO m => String -> CacheT m (Maybe String)+evaluateSpecUsingCache spec =+ CacheT $ StateT $ \c ->+ do mstr <- evalSpec spec c+ return (mstr,c)+-}+foreign import ccall "blkid_evaluate_tag" evaluate_tag :: CString+ -> CString+ -> Ptr BlkidCache+ -> IO CString++foreign import ccall "blkid_evaluate_spec" evaluate_spec :: CString+ -> Ptr BlkidCache+ -> IO CString
+ System/Linux/Blkid/Probe.hsc view
@@ -0,0 +1,1003 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ForeignFunctionInterface #-}++-- | Low-level probing functions.+module System.Linux.Blkid.Probe+ ( -- * Low-level probing+ Probe+-- , ProbeT+-- , useProbe+ , newProbe+ , newProbeFromFilename+ , probeGetDevno+ , probeGetFd+ , probeGetSectorsize+ , probeGetSectors+ , probeGetSize+ , probeGetOffset+ , probeGetWholediskDevno+ , probeSetDevice+ , probeIsWholedisk+ , resetProbe+ -- * Low-level tags+ , doProbe+ , doFullprobe+ , doSafeprobe+ , doWipe+ , probeGetValues+ , probeHasValue+ , probeLookupValue+ -- * Miscellaneous utils+ , Offset+ , Size+ -- * Topology information+ , Topology (..)+ , probeEnableTopology+ , probeGetTopology+ -- * Superblocks probing+ , probeEnableSuperblocks+ , knownFstype+ , superblocksGetName+ , probeFilterSuperblocksTypeNotIn+ , probeFilterSuperblocksTypeOnlyIn+ , Usage (..)+ , probeFilterSuperblocksUsageNotIn+ , probeFilterSuperblocksUsageOnlyIn+ , probeInvertSuperblocksFilter+ , probeResetSuperblocksFilter+ , Superblock(..)+ , defaultSuperblock+ , probeSetSuperblocksFlags+ -- * Partitions probing+ , Partition(..)+-- , Partlist+ , PartTable(..)+ , probeEnablePartitions+ , PartsFlags(..)+ , probeSetPartitionsFlags+ , probeFilterPartitionsTypeNotIn+ , probeFilterPartitionsTypeOnlyIn+ , probeInvertPartitionsFilter+ , probeResetPartitionsFilter+ , knownPttype+{-+ , partitionGetName+ , partitionGetFlags+ , partitionGetPartno+ , partitionGetSize+ , partitionGetStart+ , partitionGetTable+ , partitionGetType+ , partitionGetTypeString+ , partitionGetUUID+ , partitionIsExtended+ , partitionIsLogical+ , partitionIsPrimary+-}+ , probeDevnoToPartition+{-+ , parttableGetOffset+ , parttableGetParent+ , parttableGetType+-}+-- , probeGetPartitions+ , probeGetPartList+ ) where++import Control.Exception (bracket)+--import Control.Monad.IO.Class+--import Control.Monad.Trans.Class+--import Control.Monad.Trans.State+import Foreign+import Foreign.C+import System.Linux.Blkid.Utils (Size)+import System.Posix.Types (CDev(..), Fd(..))++#include <blkid/blkid.h>+{-+newtype ProbeT m a = ProbeT { runProbeT :: StateT BlkidProbe m a}++instance MonadTrans ProbeT where+ lift = ProbeT . lift++instance Functor f => Functor (ProbeT f) where+ fmap f = ProbeT . (fmap f) . runProbeT++instance Monad m => Monad (ProbeT m) where+ return = ProbeT . return+ (ProbeT m) >>= f = ProbeT (m >>= runProbeT . f)+ fail = ProbeT . fail++instance MonadIO m => MonadIO (ProbeT m) where+ liftIO = ProbeT . liftIO++useProbe :: MonadIO m => FilePath -> ProbeT m a -> m a+useProbe path (ProbeT f) =+ do pr <- liftIO $ withCString path $ \p ->+ throwIfNull "blkid_new_probe_from_filename returned NULL" $+ new_probe_from_filename p+ (a,pr') <- runStateT f pr+ liftIO $ free_probe pr'+ return a+-}+foreign import ccall "stdlib.h free"+ c_free :: Ptr a -> IO ()++type BlkidProbe = Ptr Probe++-- | Low-level probing setting.+newtype Probe = Probe (ForeignPtr Probe)++withProbe :: Probe -> (Ptr Probe -> IO a) -> IO a+withProbe (Probe p) = withForeignPtr p++toProbe :: Ptr Probe -> IO Probe+toProbe p = newForeignPtr p_free_probe p >>= return . Probe++type BlkidTopology = Ptr Topology++-- | Offset of a device or partition.+type Offset = Word64++-- | Data structure for topology information.+data Topology = Topology { alignmentOffset :: Offset+ , minimumIOSize :: Size+ , optimalIOSize :: Size+ , logicalSectorSize :: Size+ , physicalSectorSize :: Size+ } deriving (Eq, Show)++type BlkidPartlist = Ptr Partlist++data Partlist++type BlkidParttable = Ptr PartTable++type BlkidPartition = Ptr Partition++-- | The information about a partition as returned by+-- @'probeDevnoToPartition'@ and @'probeGetPartList'@.+data Partition = Partition+ { partitionStart :: Offset+ , partitionSize :: Size+ , partitionType :: Int -- ^ Partition type.+ , partitionTypeStr :: Maybe String -- ^ Partition type string or+ -- @'Nothing'@. The type+ -- string is supported by a+ -- small subset of partition+ -- tables (e.g Mac and EFI+ -- GPT). Note that GPT uses+ -- type UUID and this+ -- function returns this UUID+ -- as string.+ , partitionFlags :: Word64 -- ^ Partition flags (or attributes+ -- for @gpt@).+ , partitionNumber :: Int -- ^ Proposed partition number+ -- (e.g. 'N' from sda'N') or+ -- @'Control.Exception.throw'@ an+ -- error. Note that the number is+ -- generated by library independenly+ -- on your OS.+ , partitionUUID :: Maybe String -- ^ Partition UUID string if+ -- supported by partition+ -- table (e.g. GPT) or+ -- @'Nothing'@.+ , partitionName :: Maybe String -- ^ Partition name if+ -- supported by partition+ -- table (e.g. Mac) or+ -- @'Nothing'@.+ , partitionPartTable :: PartTable+ , isExtended :: Bool -- ^ Check if partition is extended (dos,+ -- windows or linux) partition.+ , isLogical :: Bool -- ^ Check if partition is logical partition.+ --+ -- Note: that this function returns @'True'@+ -- for all partitions in all nested partition+ -- tables (e.g. BSD labels).+ , isPrimary :: Bool -- ^ Check if partition is primary partition.+ --+ -- Note: this function returns @'False'@ for+ -- DOS extended partitions and all partitions+ -- in nested partition tables.+ } deriving (Eq, Show)++toPartition :: BlkidPartition -> IO Partition+toPartition p =+ do sta <- partition_get_start p >>= return . fromIntegral+ siz <- partition_get_size p >>= return . fromIntegral+ typ <- partition_get_type p >>= return . fromIntegral+ str <- partition_get_type_string p >>= maybePeek peekCString+ fla <- partition_get_flags p >>= return . fromIntegral+ pno <- partition_get_partno p >>= return . fromIntegral+ uuid <- partition_get_uuid p >>= maybePeek peekCString+ nam <- partition_get_name p >>= maybePeek peekCString+ tab <- partition_get_table p >>= toPartTable+ ext <- partition_is_extended p >>= return . toBool+ logi <- partition_is_logical p >>= return . toBool+ pri <- partition_is_primary p >>= return . toBool+ return $ Partition sta siz typ str fla pno uuid nam tab ext logi pri++-- | The information about a partition table, as returned by+-- @'probeGetPartList'@.+data PartTable = PartTable+ { parttableType :: String -- ^ Partition table type (type name,+ -- e.g. \"dos\", \"gpt\", ...).+ , parttableOffset :: Offset -- ^ Position (in bytes) of the+ -- partition table.+ --+ -- Note: the position is relative to+ -- begin of the device as defined by+ -- @'probeSetDevice'@ for primary+ -- partition table, and relative to+ -- parental partition for nested+ -- patition tables.+ , parttableParent :: Maybe Partition -- ^ Parent for nested+ -- partitition tables or+ -- @'Nothing'@.+ } deriving (Eq, Show)++toPartTable :: BlkidParttable -> IO PartTable+toPartTable pt =+ do typ <- parttable_get_type pt >>= peekCString+ off <- parttable_get_offset pt >>= return . fromIntegral+ par <- parttable_get_parent pt >>= maybePeek toPartition+ return $ PartTable typ off par++-- | Usage filter to use with @'probeFilterSuperblocksUsageNotIn'@ and+-- @'probeFilterSuperblocksUsageOnlyIn'@.+data Usage = Filesystem+ | Raid+ | Crypto+ | Other+ deriving (Eq, Show)++fromUsage :: Num a => Usage -> a+fromUsage Filesystem = #{const BLKID_USAGE_FILESYSTEM}+fromUsage Raid = #{const BLKID_USAGE_RAID}+fromUsage Crypto = #{const BLKID_USAGE_CRYPTO}+fromUsage Other = #{const BLKID_USAGE_OTHER}++toUsage :: (Eq a, Num a) => a -> Maybe Usage+toUsage #{const BLKID_USAGE_FILESYSTEM} = Just Filesystem+toUsage #{const BLKID_USAGE_RAID} = Just Raid+toUsage #{const BLKID_USAGE_CRYPTO} = Just Crypto+toUsage #{const BLKID_USAGE_OTHER} = Just Other+toUsage _ = Nothing+++-- | Create a new @'Probe'@ data structure, to use with+-- @'probeSetDevice'@.+newProbe :: IO Probe+newProbe = do p <- new_probe+ if p == nullPtr+ then fail "blkid_new_probe returned NULL"+ else toProbe p++-- | This function is same as+--+-- > \path -> do fd <- openFd path ReadOnly Nothing defaultFileFlags+-- > pr <- newProbe+-- > probeSetDevice pr fd 0 0+-- > return pr+newProbeFromFilename :: FilePath -> IO Probe+newProbeFromFilename path =+ withCString path $ \cstr ->+ do p <- new_probe_from_filename cstr+ if p == nullPtr+ then fail "blkid_new_probe_from_filename returned NULL"+ else toProbe p ++-- | Get the device number of the probed device.+probeGetDevno :: Probe -> IO (Maybe CDev)+probeGetDevno pr = withProbe pr $ \p -> do d <- probe_get_devno p+ case d of+ 0 -> return Nothing+ _ -> return $ Just d++-- | Get the file descriptor of the probed device.+probeGetFd :: Probe -> IO Fd+probeGetFd pr = withProbe pr $ \p -> probe_get_fd p >>= return . Fd++-- | Get the logical sector size of the probed device.+probeGetSectorsize :: Maybe Probe -> IO Word+probeGetSectorsize mpr =+ maybeWith withProbe mpr $ \p -> probe_get_sectorsize p >>= return . fromIntegral++-- | Get the 512-byte sector count of the probed device.+probeGetSectors :: Probe -> IO Word64+probeGetSectors pr =+ withProbe pr $ \p ->+ throwIfNeg (\e -> "blkid_probe_get_sectors returned " ++ show e) (probe_get_sectors p) >>= return . fromIntegral++-- | Return the size in bytes of the probing area as defined by+-- @'probeSetDevice'@. If the size of the probing area is unrestricted+-- then this function returns the real size of device. See also+-- @'System.Linux.Blkid.Utils.getDevSize'@.+probeGetSize :: Probe -> IO Size+probeGetSize pr =+ withProbe pr $ \p ->+ throwIfNeg (\e -> "blkid_probe_get_size returned " ++ show e) (probe_get_size p) >>= return . fromIntegral++-- | Return the offset in bytes of the probing area as defined by+-- @'probeSetDevice'@.+probeGetOffset :: Probe -> IO Offset+probeGetOffset pr =+ withProbe pr $ \p ->+ throwIfNeg (\e -> "blkid_probe_get_offset returned " ++ show e) (probe_get_offset p) >>= return . fromIntegral++-- | Return device number of the wholedisk, or 0 for regular files.+probeGetWholediskDevno :: Probe -> IO (Maybe CDev)+probeGetWholediskDevno pr =+ withProbe pr $ \p -> do d <- probe_get_wholedisk_devno p+ case d of+ 0 -> return Nothing+ _ -> return $ Just d++-- | Assigns the device to @'Probe'@ control struct, resets internal+-- buffers and resets the current probing.+probeSetDevice :: Probe+ -> Fd -- ^ Device file descriptor+ -> Offset -- ^ Begin of probing area+ -> Size -- ^ Size of probing area (zero means whole+ -- device/file)+ -> IO ()+probeSetDevice pr (Fd n) off size =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_set_device returned " ++ show e)+ (probe_set_device p n (fromIntegral off) (fromIntegral size))++-- | Check if device is whole-disk.+probeIsWholedisk :: Probe -> IO Bool+probeIsWholedisk pr =+ withProbe pr $ \p -> probe_is_wholedisk p >>= return . toEnum . fromIntegral++-- | Zeroize probing results and resets the current probing (this has+-- impact to @'doProbe'@ only). This function does not touch probing+-- filters and keeps assigned device.+resetProbe :: Probe -> IO ()+resetProbe pr = withProbe pr reset_probe++-- | Enable/disable the topology probing for non-binary interface.+probeEnableTopology :: Probe -> Bool -> IO ()+probeEnableTopology pr b =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_enable_topology returned " ++ show e)+ (probe_enable_topology p (fromBool b))++-- | Get topology information. +--+-- This function is independent on @'doProbe'@, @'doSafeprobe'@,+-- @'doFullprobe'@ and @'probeEnableTopology'@ functions.+probeGetTopology :: Probe -> IO Topology+probeGetTopology pr =+ withProbe pr $ \p -> bracket+ (probe_get_topology p)+ c_free+ (\t ->+ if t == nullPtr+ then fail "blkid_probe_get_topology returned NULL"+ else do ao <- topology_get_alignment_offset t+ mio <- topology_get_minimum_io_size t+ oio <- topology_get_optimal_io_size t+ ls <- topology_get_logical_sector_size t+ ps <- topology_get_physical_sector_size t+ return (Topology+ (fromIntegral ao)+ (fromIntegral mio)+ (fromIntegral oio)+ (fromIntegral ls)+ (fromIntegral ps)+ ))++-- | Enable/disable the superblocks probing for non-binary interface.+probeEnableSuperblocks :: Probe -> Bool -> IO ()+probeEnableSuperblocks pr b =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_enable_superblocks returned " ++ show e)+ (probe_enable_superblocks p (fromBool b))++-- | Check if the filesystem is of known type.+knownFstype :: String -> IO Bool+knownFstype str =+ withCString str $ \cstr -> known_fstype cstr >>= return . toBool++-- | Table of superblocks name and usage.+superblocksGetName :: CSize -> IO (Maybe (String, Usage))+superblocksGetName s = alloca $ \p ->+ alloca $ \q -> do+ e <- superblocks_get_name s p q+ case e of+ 0 -> do str <- peek p >>= peekCString+ i <- peek q+ let Just u = toUsage i+ return $ Just (str, u)+ _ -> return Nothing++withCStringArray :: [String] -> (Ptr CString -> IO a) -> IO a+withCStringArray xs f = bracket+ (mapM newCString xs)+ (mapM_ free)+ (\ps -> withArray0 nullPtr ps f)++probeFilterSuperblocksType :: CInt -> [String] -> Probe -> IO ()+probeFilterSuperblocksType fl xs pr =+ withProbe pr $ \p ->+ withCStringArray xs $ \cs ->+ throwIfNeg_ (\e -> "blkid_probe_filter_superblocks_type returned " ++ show e)+ (probe_filter_superblocks_type p fl cs)++-- | Probe for all superblocks whose type is not in the list.+probeFilterSuperblocksTypeNotIn :: [String] -> Probe -> IO ()+probeFilterSuperblocksTypeNotIn =+ probeFilterSuperblocksType #{const BLKID_FLTR_NOTIN}++-- | Probe only for superblocks whose type is in the list.+probeFilterSuperblocksTypeOnlyIn :: [String] -> Probe -> IO ()+probeFilterSuperblocksTypeOnlyIn =+ probeFilterSuperblocksType #{const BLKID_FLTR_ONLYIN}++probeFilterSuperblocksUsage :: CInt -> [Usage] -> Probe -> IO ()+probeFilterSuperblocksUsage fl us pr =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_filter_superblocks_usage returned " ++ show e)+ (probe_filter_superblocks_usage p fl (foldl1 (.|.) $ map fromUsage us))++-- | Probe for all superblocks whose @'Usage'@ is not in the list.+probeFilterSuperblocksUsageNotIn :: [Usage] -> Probe -> IO ()+probeFilterSuperblocksUsageNotIn =+ probeFilterSuperblocksUsage #{const BLKID_FLTR_NOTIN}++-- | Probe only for superblocks whose @'Usage'@ is in the list.+probeFilterSuperblocksUsageOnlyIn :: [Usage] -> Probe -> IO ()+probeFilterSuperblocksUsageOnlyIn =+ probeFilterSuperblocksUsage #{const BLKID_FLTR_ONLYIN}++-- | Invert superblocks probing filter.+probeInvertSuperblocksFilter :: Probe -> IO ()+probeInvertSuperblocksFilter pr =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_invert_superblocks_filter returned " ++ show e) (probe_invert_superblocks_filter p)++-- | Reset superblocks probing filter.+probeResetSuperblocksFilter :: Probe -> IO ()+probeResetSuperblocksFilter pr =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_reset_superblocks_filter returned " ++ show e) (probe_reset_superblocks_filter p)++-- | Superblock probing flags.+data Superblock = Superblock { readLabel :: Bool+ , readLabelRaw :: Bool+ , readUUID :: Bool+ , readUUIDRaw :: Bool+ , readType :: Bool+ , readSecType :: Bool+ , readUsage :: Bool+ , readVersion :: Bool+ , readMagic :: Bool+ } deriving (Eq, Show)++-- | Default superblock flags.+defaultSuperblock :: Superblock+defaultSuperblock = Superblock True False True False True True False False False++fromSuperblock :: (Bits a, Num a) => Superblock -> a+fromSuperblock (Superblock l lr u ur t st us v m) =+ (if l then #{const BLKID_SUBLKS_LABEL} else 0) .|.+ (if lr then #{const BLKID_SUBLKS_LABELRAW} else 0) .|.+ (if u then #{const BLKID_SUBLKS_UUID} else 0) .|.+ (if ur then #{const BLKID_SUBLKS_UUIDRAW} else 0) .|.+ (if t then #{const BLKID_SUBLKS_TYPE} else 0) .|.+ (if st then #{const BLKID_SUBLKS_SECTYPE} else 0) .|.+ (if us then #{const BLKID_SUBLKS_USAGE} else 0) .|.+ (if v then #{const BLKID_SUBLKS_VERSION} else 0) .|.+ (if m then #{const BLKID_SUBLKS_MAGIC} else 0)++-- | Set probing flags to the superblocks prober. This function is+-- optional, the default is @'defaultSuperblock'@.+probeSetSuperblocksFlags :: Probe -> Superblock -> IO ()+probeSetSuperblocksFlags pr s =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_set_superblocks_flags returned " ++ show e)+ (probe_set_superblocks_flags p (fromSuperblock s))++-- | Enable/disable the partitions probing for non-binary interface.+probeEnablePartitions :: Probe -> Bool -> IO ()+probeEnablePartitions pr b =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_enable_partitions returned " ++ show e)+ (probe_enable_partitions p (fromBool b))++-- | Flags for @'probeSetPartitionsFlags'@.+data PartsFlags = PartsFlags { forceGPT :: Bool+ , entryDetails :: Bool+ , magic :: Bool+ } deriving (Eq, Show)++fromPartsFlags :: (Bits a, Num a) => PartsFlags -> a+fromPartsFlags (PartsFlags g d m) =+ (if g then #{const BLKID_PARTS_FORCE_GPT} else 0) .|.+ (if d then #{const BLKID_PARTS_ENTRY_DETAILS} else 0) .|.+ (if m then #{const BLKID_PARTS_MAGIC} else 0)++-- | Set probing flags to the partitions prober. This function is optional.+probeSetPartitionsFlags :: Probe -> PartsFlags -> IO ()+probeSetPartitionsFlags pr fl =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_set_partitions_flags returned " ++ show e)+ (probe_set_partitions_flags p (fromPartsFlags fl))++probeFilterPartitionsType :: CInt -> [String] -> Probe -> IO ()+probeFilterPartitionsType i xs pr =+ withProbe pr $ \p ->+ withCStringArray xs $ \arr ->+ throwIfNeg_ (\e -> "blkid_probe_filter_partitions_type returned " ++ show e)+ (probe_filter_partitions_type p i arr)++-- | Probe for all partitions whose type is not in the list.+probeFilterPartitionsTypeNotIn :: [String] -> Probe -> IO ()+probeFilterPartitionsTypeNotIn =+ probeFilterPartitionsType #{const BLKID_FLTR_NOTIN}++-- | Probe only for partitions whose type is the list.+probeFilterPartitionsTypeOnlyIn :: [String] -> Probe -> IO ()+probeFilterPartitionsTypeOnlyIn =+ probeFilterPartitionsType #{const BLKID_FLTR_ONLYIN}++-- | Invert partitions probing filter.+probeInvertPartitionsFilter :: Probe -> IO ()+probeInvertPartitionsFilter pr =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_invert_partitions_filter returned " ++ show e) (probe_invert_partitions_filter p)++-- | Reset partitions probing filter.+probeResetPartitionsFilter :: Probe -> IO ()+probeResetPartitionsFilter pr =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_probe_reset_partitions_filter returned " ++ show e) (probe_reset_partitions_filter p)++-- | Check if the partition if of known type.+knownPttype :: String -> IO Bool+knownPttype str =+ withCString str $ \cstr -> known_pttype cstr >>= return . toBool+{-+-- | Get partition name if supported by partition table (e.g. Mac) or+-- @'Nothing'@.+partitionGetName :: Partition -> IO (Maybe String)+partitionGetName part =+ withPartition part $ \p -> partition_get_name p >>= maybePeek peekCString++-- | get partition flags (or attributes for @gpt@).+partitionGetFlags :: Partition -> IO Word64+partitionGetFlags part =+ withPartition part $ \p -> partition_get_flags p >>= return . fromIntegral++-- | Proposed partitin number (e.g. 'N' from sda'N') or+-- @'Control.Exception.throw'@ an error. Note that the number is+-- generated by library independenly on your OS.+partitionGetPartno :: Partition -> IO Int+partitionGetPartno part =+ withPartition part $ \p ->+ throwIfNeg (\e -> "blkid_partition_get_partno returned " ++ show e) (partition_get_partno p)+ >>= return . fromIntegral++partitionGetSize :: Partition -> IO Size+partitionGetSize part =+ withPartition part $ \p -> partition_get_size p >>= return . fromIntegral++partitionGetStart :: Partition -> IO Offset+partitionGetStart part =+ withPartition part $ \p -> partition_get_start p >>= return . fromIntegral++partitionGetTable :: Partition -> IO PartTable+partitionGetTable part = withPartition part $ \p ->+ do q <- partition_get_table p+ if q == nullPtr+ then fail+ "blkid_partition_get_table returned NULL"+ else toPartTable q++-- | Get partition type.+partitionGetType :: Partition -> IO Int+partitionGetType part =+ withPartition part $ \p -> partition_get_type p >>= return . fromIntegral++-- | Get partition type string or @'Nothing'@. The type string is+-- supported by a small subset of partition tables (e.g Mac and EFI+-- GPT). Note that GPT uses type UUID and this function returns this+-- UUID as string.+partitionGetTypeString :: Partition -> IO (Maybe String)+partitionGetTypeString part =+ withPartition part $ \p ->+ partition_get_type_string p >>= maybePeek peekCString++-- | Get partition UUID string if supported by partition table+-- (e.g. GPT) or @'Nothing'@.+partitionGetUUID :: Partition -> IO (Maybe String)+partitionGetUUID part =+ withPartition part $ \p -> partition_get_uuid p >>= maybePeek peekCString++-- | Check if partition is extended (dos, windows or linux) partition.+partitionIsExtended :: Partition -> IO Bool+partitionIsExtended part =+ withPartition part $ \p -> partition_is_extended p >>= return . toBool++-- | Check if partition is logical partition.+--+-- Note: that this function returns @'True'@ for all partitions in all+-- nested partition tables (e.g. BSD labels).+partitionIsLogical :: Partition -> IO Bool+partitionIsLogical part =+ withPartition part $ \p -> partition_is_logical p >>= return . toBool++-- | Check if partition is primary partition.+--+-- Note: this function returns @'False'@ for DOS extended partitions+-- and all partitions in nested partition tables.+partitionIsPrimary :: Partition -> IO Bool+partitionIsPrimary part =+ withPartition part $ \p -> partition_is_primary p >>= return . toBool+-}+-- | This function tries to get start and size for devno from @sysfs@+-- and returns a partition which matches with the values from @sysfs@.+--+-- This function is independent on @'doProbe'@, @'doSafeprobe'@,+-- @'doFullprobe'@ and @'probeEnablePartitions'@ functions.+probeDevnoToPartition :: Probe -> CDev -> IO (Maybe Partition)+probeDevnoToPartition pr d =+ withProbe pr $ \p ->+ do pl <- throwIfNull "blkid_probe_get_partitions returned NULL" $+ probe_get_partitions p+ partlist_devno_to_partition pl d >>= maybePeek toPartition+{-+-- | Get the position (in bytes) of the partition table.+--+-- Note: the position is relative to begin of the device as defined by+-- @'probeSetDevice'@ for primary partition table, and relative to+-- parental partition for nested patition tables.+parttableGetOffset :: PartTable -> IO Offset+parttableGetOffset pt =+ withPartTable pt $ \p -> parttable_get_offset p >>= return . fromIntegral++-- | Get parent for nexted partitition tables or @'Nothing'@.+parttableGetParent :: PartTable -> IO (Maybe Partition)+parttableGetParent pt =+ withPartTable pt $ \p -> parttable_get_parent p >>= maybePeek toPartition++-- | Get partition table type (type name, e.g. \"dos\", \"gpt\", ...).+parttableGetType :: PartTable -> IO String+parttableGetType pt =+ withPartTable pt $ \p -> parttable_get_type p >>= peekCString+-}+-- | Get partition list.+--+-- This function is independent on @'doProbe'@, @'doSafeprobe'@,+-- @'doFullprobe'@ and @'probeEnablePartitions'@ functions.+probeGetPartList :: Probe -> IO (Maybe PartTable, [Partition])+probeGetPartList pr =+ withProbe pr $ \p ->+ do pl <- throwIfNull "blkid_probe_get_partitions returned NULL" $+ probe_get_partitions p+ mpt <- partlist_get_table pl >>= maybePeek toPartTable+ n <- partlist_numof_partitions pl+ parts <- mapM (getPart pl) [0..n-1]+ return (mpt, parts)+ where getPart plist i =+ throwIfNull "blkid_partlist_get_partition returned NULL"+ (partlist_get_partition plist i) >>= toPartition+ +-- | Get the list of probed @(key,value)@ pairs.+probeGetValues :: Probe -> IO [(String,String)]+probeGetValues pr =+ withProbe pr $ \p ->+ do n <- throwIfNeg (\e -> "blkid_probe_numof_values returned " +++ show e) $ probe_numof_values p+ if n == 0+ then return []+ else mapM (getValue p) [0..n-1]+ where getValue r i =+ alloca $ \pn ->+ alloca $ \pd ->+ alloca $ \ps ->+ do throwIfNeg_ (\e -> "blkid_probe_get_value returned " ++ show e)+ (probe_get_value r i pn pd ps) + n <- peek pn >>= peekCString+ d <- peek pd >>= peekCString+ return (n,d)++-- | Test if a given key has a value.+probeHasValue :: Probe -> String -> IO Bool+probeHasValue pr str =+ withProbe pr $ \p ->+ withCString str $ \cstr ->+ probe_has_value p cstr >>= return . toBool++-- | Lookup the value for the given key, and return it if present.+probeLookupValue :: Probe -> String -> IO (Maybe String)+probeLookupValue pr str =+ withProbe pr $ \p ->+ withCString str $ \cstr ->+ alloca $ \pd ->+ alloca $ \ps ->+ do e <- probe_lookup_value p cstr pd ps+ case e of+ 0 -> peek pd >>= peekCString >>= return . Just+ (-1) -> return Nothing+ _ -> fail+ ("blkid_probe_lookup_value returned " ++ show e)++-- | This function erases the current signature detected by+-- @'Probe'@. The @'Probe'@ has to be open in+-- @'System.Posix.IO.ReadWrite'@ mode, and either use+-- @'probeSetSuperblocksFlags'@ with @'readMagic'@ set to @'True'@, or+-- use @'probeSetPartitionsFlags'@ with @'magic'@ set to @'True'@.+--+-- After successful signature removing the @'Probe'@ will be moved one+-- step back and the next @'doProbe'@ call will again call previously+-- called probing function.+doWipe :: Probe -> Bool -> IO ()+doWipe pr b =+ withProbe pr $ \p ->+ throwIfNeg_ (\e -> "blkid_do_wipe returned " ++ show e) (do_wipe p (fromBool b))++-- | Call probing functions in all enabled chains. The superblocks+-- chain is enabled by default. @'doProbe'@ stores result from only+-- one probing function. Use @'probeGetValues'@ to get results from+-- all probing functions in all chains. The probing is reset by+-- @'resetProbe'@ or by filter functions.+--+-- This is string-based @(key,value)@ interface only.+doProbe :: Probe -> IO Bool+doProbe pr =+ withProbe pr $ \p ->+ throwIfNeg (\e -> "blkid_do_probe returned " ++ show e) (do_probe p)+ >>= return . not . toBool++-- | This function gathers probing results from all enabled+-- chains. Same as @'doSafeprobe'@ but does not check for collision+-- between probing result.+--+-- This is string-based @(key,value)@ interface only.+doFullprobe :: Probe -> IO Bool+doFullprobe pr =+ withProbe pr $ \p ->+ throwIfNeg (\e -> "blkid_do_fullprobe returned " ++ show e)+ (do_fullprobe p) >>= return . not . toBool++-- | This function gathers probing results from all enabled chains and checks for ambivalent results (e.g. more filesystems on the device).+--+-- This is string-based @(key,value)@ interface only.+--+-- Note about suberblocks chain: the function does not check for+-- filesystems when a RAID signature is detected. The function also+-- does not check for collision between RAIDs. The first detected RAID+-- is returned. The function checks for collision between partition+-- table and RAID signature -- it's recommended to enable partitions+-- chain together with superblocks chain.+doSafeprobe :: Probe+ -> IO (Maybe Bool) -- ^ @'Just' 'True'@ on success,+ -- @'Just' 'False'@ if nothing is+ -- detected, @'Nothing'@ if ambivalent+ -- result is detected.+doSafeprobe pr =+ withProbe pr $ \p ->+ do n <- do_safeprobe p+ case n of+ 1 -> return $ Just False+ 0 -> return $ Just True+ (-2) -> return Nothing+ e -> fail ("blkid_do_safeprobe returned " ++ show e)++type BlkidLoff = #{type blkid_loff_t}++{-+foreign import ccall "blkid_parse_tag_string"+ parse_tag_string :: CString -> Ptr CString -> Ptr CString -> IO CInt++foreign import ccall "blkid_parse_version_string"+ parse_version_string :: CString -> IO CInt++foreign import ccall "blkid_get_library_version"+ get_library_version :: Ptr CString -> Ptr CString -> IO CInt++foreign import ccall "blkid_encode_string" encode_string :: CString+ -> CString+ -> CSize+ -> IO CInt++foreign import ccall "blkid_safe_string" safe_string :: CString+ -> CString+ -> CSize+ -> IO CInt+-}+foreign import ccall "blkid_new_probe" new_probe :: IO BlkidProbe++foreign import ccall "blkid_new_probe_from_filename"+ new_probe_from_filename :: CString -> IO BlkidProbe++foreign import ccall "&blkid_free_probe"+ p_free_probe :: FunPtr (BlkidProbe -> IO ())++--foreign import ccall "blkid_free_probe" free_probe :: BlkidProbe -> IO ()++foreign import ccall "blkid_reset_probe" reset_probe :: BlkidProbe+ -> IO ()++foreign import ccall "blkid_probe_set_device" probe_set_device :: BlkidProbe+ -> CInt+ -> BlkidLoff+ -> BlkidLoff+ -> IO CInt++foreign import ccall "blkid_probe_get_devno" probe_get_devno :: BlkidProbe+ -> IO CDev++foreign import ccall "blkid_probe_get_wholedisk_devno"+ probe_get_wholedisk_devno :: BlkidProbe -> IO CDev++foreign import ccall "blkid_probe_is_wholedisk" probe_is_wholedisk :: BlkidProbe+ -> IO CInt++foreign import ccall "blkid_probe_get_size" probe_get_size :: BlkidProbe+ -> IO BlkidLoff++foreign import ccall "blkid_probe_get_offset" probe_get_offset :: BlkidProbe+ -> IO BlkidLoff++foreign import ccall "blkid_probe_get_sectorsize"+ probe_get_sectorsize :: BlkidProbe -> IO CUInt++foreign import ccall "blkid_probe_get_sectors" probe_get_sectors :: BlkidProbe+ -> IO BlkidLoff++foreign import ccall "blkid_probe_get_fd" probe_get_fd :: BlkidProbe+ -> IO CInt++foreign import ccall "blkid_known_fstype" known_fstype :: CString -> IO CInt++foreign import ccall "blkid_superblocks_get_name"+ superblocks_get_name :: CSize -> Ptr CString -> Ptr CInt -> IO CInt++foreign import ccall "blkid_probe_enable_superblocks"+ probe_enable_superblocks :: BlkidProbe -> CInt -> IO CInt++foreign import ccall "blkid_probe_set_superblocks_flags"+ probe_set_superblocks_flags :: BlkidProbe -> CInt -> IO CInt++foreign import ccall "blkid_probe_reset_superblocks_filter"+ probe_reset_superblocks_filter :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_invert_superblocks_filter"+ probe_invert_superblocks_filter :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_filter_superblocks_type"+ probe_filter_superblocks_type :: BlkidProbe -> CInt -> Ptr CString -> IO CInt++foreign import ccall "blkid_probe_filter_superblocks_usage"+ probe_filter_superblocks_usage :: BlkidProbe -> CInt -> CInt -> IO CInt++foreign import ccall "blkid_probe_enable_topology"+ probe_enable_topology :: BlkidProbe -> CInt -> IO CInt++foreign import ccall "blkid_probe_get_topology"+ probe_get_topology :: BlkidProbe -> IO BlkidTopology++foreign import ccall "blkid_topology_get_alignment_offset"+ topology_get_alignment_offset :: BlkidTopology -> IO CUInt++foreign import ccall "blkid_topology_get_minimum_io_size"+ topology_get_minimum_io_size :: BlkidTopology -> IO CUInt++foreign import ccall "blkid_topology_get_optimal_io_size"+ topology_get_optimal_io_size :: BlkidTopology -> IO CUInt++foreign import ccall "blkid_topology_get_logical_sector_size"+ topology_get_logical_sector_size :: BlkidTopology -> IO CUInt++foreign import ccall "blkid_topology_get_physical_sector_size"+ topology_get_physical_sector_size :: BlkidTopology -> IO CUInt++foreign import ccall "blkid_known_pttype" known_pttype :: CString -> IO CInt++foreign import ccall "blkid_probe_enable_partitions"+ probe_enable_partitions :: BlkidProbe -> CInt -> IO CInt++foreign import ccall "blkid_probe_reset_partitions_filter"+ probe_reset_partitions_filter :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_invert_partitions_filter"+ probe_invert_partitions_filter :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_filter_partitions_type"+ probe_filter_partitions_type :: BlkidProbe -> CInt -> Ptr CString -> IO CInt++foreign import ccall "blkid_probe_set_partitions_flags"+ probe_set_partitions_flags :: BlkidProbe -> CInt -> IO CInt++foreign import ccall "blkid_probe_get_partitions"+ probe_get_partitions :: BlkidProbe -> IO BlkidPartlist++foreign import ccall "blkid_partlist_numof_partitions"+ partlist_numof_partitions :: BlkidPartlist -> IO CInt++foreign import ccall "blkid_partlist_get_table"+ partlist_get_table :: BlkidPartlist -> IO BlkidParttable++foreign import ccall "blkid_partlist_get_partition"+ partlist_get_partition :: BlkidPartlist -> CInt -> IO BlkidPartition++foreign import ccall "blkid_partlist_devno_to_partition"+ partlist_devno_to_partition :: BlkidPartlist -> CDev -> IO BlkidPartition++foreign import ccall "blkid_partition_get_table"+ partition_get_table :: BlkidPartition -> IO BlkidParttable++foreign import ccall "blkid_partition_get_name"+ partition_get_name :: BlkidPartition -> IO CString++foreign import ccall "blkid_partition_get_uuid"+ partition_get_uuid :: BlkidPartition -> IO CString++foreign import ccall "blkid_partition_get_partno"+ partition_get_partno :: BlkidPartition -> IO CInt++foreign import ccall "blkid_partition_get_start"+ partition_get_start :: BlkidPartition -> IO BlkidLoff++foreign import ccall "blkid_partition_get_size"+ partition_get_size :: BlkidPartition -> IO BlkidLoff++foreign import ccall "blkid_partition_get_type"+ partition_get_type :: BlkidPartition -> IO CInt++foreign import ccall "blkid_partition_get_type_string"+ partition_get_type_string :: BlkidPartition -> IO CString++foreign import ccall "blkid_partition_get_flags"+ partition_get_flags :: BlkidPartition -> IO CULLong++foreign import ccall "blkid_partition_is_logical"+ partition_is_logical :: BlkidPartition -> IO CInt++foreign import ccall "blkid_partition_is_extended"+ partition_is_extended :: BlkidPartition -> IO CInt++foreign import ccall "blkid_partition_is_primary"+ partition_is_primary :: BlkidPartition -> IO CInt++foreign import ccall "blkid_parttable_get_type"+ parttable_get_type :: BlkidParttable -> IO CString++foreign import ccall "blkid_parttable_get_offset"+ parttable_get_offset :: BlkidParttable -> IO BlkidLoff++foreign import ccall "blkid_parttable_get_parent"+ parttable_get_parent :: BlkidParttable -> IO BlkidPartition++foreign import ccall "blkid_do_probe" do_probe :: BlkidProbe -> IO CInt++foreign import ccall "blkid_do_safeprobe" do_safeprobe :: BlkidProbe -> IO CInt++foreign import ccall "blkid_do_fullprobe" do_fullprobe :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_numof_values"+ probe_numof_values :: BlkidProbe -> IO CInt++foreign import ccall "blkid_probe_get_value" probe_get_value :: BlkidProbe+ -> CInt+ -> Ptr CString+ -> Ptr CString+ -> Ptr CSize+ -> IO CInt++foreign import ccall "blkid_probe_lookup_value" probe_lookup_value :: BlkidProbe+ -> CString+ -> Ptr CString+ -> Ptr CSize+ -> IO CInt++foreign import ccall "blkid_probe_has_value" probe_has_value :: BlkidProbe+ -> CString+ -> IO CInt++foreign import ccall "blkid_do_wipe" do_wipe :: BlkidProbe -> CInt -> IO CInt+
+ System/Linux/Blkid/Utils.hsc view
@@ -0,0 +1,86 @@+{-# LANGUAGE ForeignFunctionInterface #-}++-- | Utilities for low-level and high-level API.+module System.Linux.Blkid.Utils+ ( Size+ , devnoToDevname+ , devnoToWholedisk+ , getDevSize+ , libraryVersion+ , libraryReleaseDate+ , sendUevent+ ) where++import Control.Exception (bracket)+import Foreign+import Foreign.C+import System.Posix.Types (CDev(..), Fd(..))++#include <blkid/blkid.h>++foreign import ccall "stdlib.h free"+ c_free :: Ptr a -> IO ()++type BlkidLoff = #{type blkid_loff_t}++-- | Size of a device or partition.+type Size = Word64++-- | Find the pathname to a block device with a given device number.+--+-- >>> devnoToDevname 0x0800+-- Just "/dev/sda"+devnoToDevname :: CDev -> IO (Maybe String)+devnoToDevname d = bracket (devno_to_devname d) c_free (maybePeek peekCString)++-- | Convert the @'CDev'@ device number to the /name/ of the whole+-- disk. The function DOES NOT return full device name. The @'CDev'@+-- argument could be partition or whole disk -- both are converted.+--+-- For example: sda1, 0x0801 --> sda, 0x0800+--+-- >>> devnoToWholedisk 0x0801+-- ("sda",2048)+devnoToWholedisk :: CDev -> IO (String, CDev)+devnoToWholedisk d =+ allocaBytes 32 $ \pc ->+ alloca $ \pd ->+ do throwIfNeg_ (\e -> "blkid_devno_to_wholedisk returned " ++ show e) (devno_to_wholedisk d pc 32 pd)+ str <- peekCString pc+ d1 <- peek pd+ return (str, d1)++-- | Send an event @'String'@ for a device.+sendUevent :: FilePath -> String -> IO ()+sendUevent path str =+ withCString path $ \p ->+ withCString str $ \s ->+ throwIfNeg_ (\e -> "blkid_send_uevent returned " ++ show e) (send_uevent p s)++-- | Get the size of a device given its file descriptor.+getDevSize :: Fd -> IO Size+getDevSize (Fd n) = get_dev_size n >>= return . fromIntegral+++-- | @libblkid@ version.+libraryVersion :: String+libraryVersion = #{const_str BLKID_VERSION}++-- | @libblkid@ release date.+libraryReleaseDate :: String+libraryReleaseDate = #{const_str BLKID_DATE}++foreign import ccall "blkid_devno_to_devname" devno_to_devname :: CDev+ -> IO CString++foreign import ccall "blkid_devno_to_wholedisk" devno_to_wholedisk :: CDev+ -> CString+ -> CSize+ -> Ptr CDev+ -> IO CInt+++foreign import ccall "blkid_get_dev_size" get_dev_size :: CInt -> IO BlkidLoff++foreign import ccall "blkid_send_uevent"+ send_uevent :: CString -> CString -> IO CInt
+ linux-blkid.cabal view
@@ -0,0 +1,26 @@+Name: linux-blkid+Version: 0.1.0.0+Cabal-Version: >= 1.8+Build-Type: Simple+License: LGPL-2.1+License-File: LICENSE+Copyright: © 2013 Nicola Squartini+Author: Nicola Squartini+Maintainer: Nicola Squartini <tensor5@gmail.com>+Bug-Reports: mailto:tensor5@gmail.com+Category: System+Stability: experimental+Synopsis: Linux libblkid+Description: Bindings to the Linux libblkid library.++Library+ Build-Depends: base == 4.*,+ transformers == 0.3.*+-- uuid == 1.2.*+ Ghc-Options: -Wall+ Exposed-modules: System.Linux.Blkid+ System.Linux.Blkid.Cache+ System.Linux.Blkid.Evaluate+ System.Linux.Blkid.Probe+ System.Linux.Blkid.Utils+ Pkgconfig-Depends: blkid