module Debian.Dpkg.DB (
msdbInit
, setDbDir
, pkgDbFind
, pkgList
, getConfigVersion
) where
import Foreign.Ptr (Ptr,FunPtr,plusPtr)
import Foreign.Ptr (wordPtrToPtr,castPtrToFunPtr)
import Foreign.Storable
import Foreign.C.Types
import Foreign.C.String (CString,CStringLen,CWString,CWStringLen)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Array (peekArray,pokeArray)
import Data.Int
import Data.Word
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 Debian.Dpkg.Types
foreign import ccall unsafe "modstatdb_open" c'modstatdb_open
:: CInt -> IO ()
foreign import ccall unsafe "&modstatdb_open" p'modstatdb_open
:: FunPtr (CInt -> IO ())
foreign import ccall unsafe "push_error_context" c'push_error_context
:: IO ()
foreign import ccall unsafe "&push_error_context" p'push_error_context
:: FunPtr (IO ())
foreign import ccall unsafe "dpkg_set_progname" c'dpkg_set_progname
:: CString -> IO ()
foreign import ccall unsafe "&dpkg_set_progname" p'dpkg_set_progname
:: FunPtr (CString -> IO ())
foreign import ccall unsafe "dpkg_db_set_dir" c'dpkg_db_set_dir
:: CString -> IO ()
foreign import ccall unsafe "&dpkg_db_set_dir" p'dpkg_db_set_dir
:: FunPtr (CString -> IO ())
foreign import ccall unsafe "pkg_db_iter_new" c'pkg_db_iter_new
:: IO (Ptr C'pkgiterator)
foreign import ccall unsafe "&pkg_db_iter_new" p'pkg_db_iter_new
:: FunPtr (IO (Ptr C'pkgiterator))
foreign import ccall unsafe "pkg_db_iter_next" c'pkg_db_iter_next
:: Ptr C'pkgiterator -> IO (Ptr C'pkginfo)
foreign import ccall unsafe "&pkg_db_iter_next" p'pkg_db_iter_next
:: FunPtr (Ptr C'pkgiterator -> IO (Ptr C'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 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
foreign import ccall unsafe "pkg_db_find" c'pkg_db_find
:: CString -> IO (Ptr C'pkginfo)
foreign import ccall unsafe "&pkg_db_find" p'pkg_db_find
:: FunPtr (CString -> IO (Ptr C'pkginfo))
pkgDbFind :: String -> IO C'pkginfo
pkgDbFind p = withCString p c'pkg_db_find >>= peek
getConfigVersion :: C'pkginfo -> IO String
getConfigVersion p = do
v <- peekCString (c'versionrevision'version vr)
r <- peekCString (c'versionrevision'revision vr)
return $ nonZeroEpoch e ++ v ++ nonNativeRevision r
where
nonZeroEpoch e = if e == 0 then "" else (show e) ++ ":"
nonNativeRevision r = if r == "" then r else "-" ++ r
e = fromIntegral (c'versionrevision'epoch vr)
vr = c'pkginfo'configversion p