1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
{-
DB.hsc: Haskell bindings to libdpkg
Copyright (C) 2011, 2012 Clint Adams
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
#include <bindings.dsl.h>
module Debian.Dpkg.DB (
msdbInit
, setDbDir
, pkgList
, parseVersion
, c'parseversion
, c'dpkg_version_compare
) where
#strict_import
import Foreign.Ptr (nullPtr)
import Foreign.C.String (withCString, peekCString)
import Foreign.Marshal.Utils (with)
import Control.Monad (liftM, join)
import Control.Monad.Loops (unfoldrM)
import qualified Data.ByteString as BS
import Debian.Dpkg.Types
#include <dpkg/dpkg-db.h>
#callconv modstatdb_open , ccall unsafe , CInt -> IO ()
#callconv push_error_context , ccall unsafe , IO ()
#callconv dpkg_set_progname , ccall unsafe , CString -> IO ()
#callconv dpkg_db_set_dir , ccall unsafe , CString -> IO ()
#callconv pkg_db_iter_new , ccall unsafe , IO (Ptr <pkgiterator>)
#callconv pkg_db_iter_next_pkg , ccall unsafe , Ptr <pkgiterator> -> IO (Ptr <pkginfo>)
msdbInit :: IO ()
msdbInit = do
c'push_error_context
c'modstatdb_open 0
withCString "haskell-dpkg" c'dpkg_set_progname
setDbDir :: String -> IO ()
setDbDir x = withCString x c'dpkg_db_set_dir
pkgDbIterNext :: Ptr C'pkgiterator -> IO (Maybe (Ptr C'pkginfo, Ptr C'pkgiterator))
pkgDbIterNext i = do
pptr <- c'pkg_db_iter_next_pkg i
if pptr == nullPtr
then
return Nothing
else
return $ Just (pptr, i)
pkgpList :: IO [Ptr C'pkginfo]
pkgpList = c'pkg_db_iter_new >>= unfoldrM (pkgDbIterNext)
pkgList :: IO [C'pkginfo]
pkgList = pkgpList >>= mapM peek
#callconv parseversion , ccall unsafe , Ptr C'dpkg_version -> CString -> Ptr C'dpkg_error -> IO CInt
#callconv dpkg_version_compare , ccall unsafe , Ptr C'dpkg_version -> Ptr C'dpkg_version -> IO CInt
parseVersion :: BS.ByteString -> IO (Either String C'dpkg_version)
parseVersion verstr = BS.useAsCString verstr $ \vercstr -> alloca $ \vrptr -> alloca $ \deptr -> do
i <- c'parseversion vrptr vercstr deptr
vr <- peek vrptr
if i == 0
then
return $ Right vr
else
do
de <- peek deptr
errmsg <- peekCString (c'dpkg_error'str de)
if (c'dpkg_error'type de) == 1
then
return $ Right vr
else
return $ Left errmsg
|