diff options
-rw-r--r-- | Assistant/Threads/MountWatcher.hs | 2 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | Utility/Mounts.hsc | 58 | ||||
-rw-r--r-- | Utility/libmounts.c | 105 | ||||
-rw-r--r-- | Utility/libmounts.h | 48 | ||||
-rw-r--r-- | debian/copyright | 13 | ||||
-rw-r--r-- | git-annex.cabal | 2 |
7 files changed, 190 insertions, 42 deletions
diff --git a/Assistant/Threads/MountWatcher.hs b/Assistant/Threads/MountWatcher.hs index f3b9c0a3a..cc62c294d 100644 --- a/Assistant/Threads/MountWatcher.hs +++ b/Assistant/Threads/MountWatcher.hs @@ -82,7 +82,7 @@ type MountPoints = S.Set FilePath {- Reads mtab, getting the current set of mount points. -} currentMountPoints :: IO MountPoints -currentMountPoints = S.fromList . map mnt_dir <$> read_mtab +currentMountPoints = S.fromList . map mnt_dir <$> getMounts {- Finds new mount points, given an old and a new set. -} newMountPoints :: MountPoints -> MountPoints -> MountPoints @@ -6,10 +6,10 @@ all=$(bins) $(mans) docs OS:=$(shell uname | sed 's/[-_].*//') ifeq ($(OS),Linux) BASEFLAGS_OPTS+=-DWITH_INOTIFY -DWITH_DBUS -clibs=Utility/libdiskfree.o +clibs=Utility/libdiskfree.o Utility/libmounts.o else BASEFLAGS_OPTS+=-DWITH_KQUEUE -clibs=Utility/libdiskfree.o Utility/libkqueue.o +clibs=Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o endif PREFIX=/usr diff --git a/Utility/Mounts.hsc b/Utility/Mounts.hsc index 622ac877a..6bcb03f2c 100644 --- a/Utility/Mounts.hsc +++ b/Utility/Mounts.hsc @@ -2,6 +2,9 @@ - - Derived from hsshellscript, originally written by - Volker Wysk <hsss@volker-wysk.de> + - + - Modified to support BSD and Mac OS X by + - Joey Hess <joey@kitenet.net> - - Licensed under the GNU LGPL version 2.1 or higher. -} @@ -10,8 +13,7 @@ module Utility.Mounts ( Mntent(..), - read_mtab, - read_fstab, + getMounts ) where import Control.Monad @@ -20,62 +22,46 @@ import Foreign.C import GHC.IO hiding (finally, bracket) import Prelude hiding (catch) -#include <stdio.h> -#include <mntent.h> +#include "libmounts.h" +{- This is a stripped down mntent, containing only + - fields available everywhere. -} data Mntent = Mntent { mnt_fsname :: String , mnt_dir :: String , mnt_type :: String - , mnt_opts :: String - , mnt_freq :: Int - , mnt_passno :: Int } deriving (Read, Show, Eq) -read_mounts :: String -> IO [Mntent] -read_mounts path = do - h <- withCString path $ \cpath -> - withCString "r" $ \r -> - c_setmntent cpath r +getMounts :: IO [Mntent] +getMounts = do + h <- c_mounts_start when (h == nullPtr) $ - throwErrno "setmntent" + throwErrno "getMounts" mntent <- getmntent h [] - _ <- c_endmntent h + _ <- c_mounts_end h return mntent where - getmntent h l = do - ptr <- c_getmntent h + getmntent h c = do + ptr <- c_mounts_next h if (ptr == nullPtr) - then return $ reverse l + then return $ reverse c else do mnt_fsname_str <- #{peek struct mntent, mnt_fsname} ptr >>= peekCString mnt_dir_str <- #{peek struct mntent, mnt_dir} ptr >>= peekCString mnt_type_str <- #{peek struct mntent, mnt_type} ptr >>= peekCString - mnt_opts_str <- #{peek struct mntent, mnt_opts} ptr >>= peekCString - mnt_freq_int <- #{peek struct mntent, mnt_freq} ptr - mnt_passno_int <- #{peek struct mntent, mnt_passno} ptr let ent = Mntent { mnt_fsname = mnt_fsname_str , mnt_dir = mnt_dir_str , mnt_type = mnt_type_str - , mnt_opts = mnt_opts_str - , mnt_freq = mnt_freq_int - , mnt_passno = mnt_passno_int } - getmntent h (ent:l) - -read_mtab :: IO [Mntent] -read_mtab = read_mounts "/etc/mtab" - -read_fstab :: IO [Mntent] -read_fstab = read_mounts "/etc/fstab" + getmntent h (ent:c) -foreign import ccall safe "setmntent" - c_setmntent :: ((Ptr CChar) -> ((Ptr CChar) -> (IO (Ptr ())))) +foreign import ccall unsafe "libmounts.h mounts_start" c_mounts_start + :: IO (Ptr ()) -foreign import ccall safe "endmntent" - c_endmntent :: ((Ptr ()) -> (IO CInt)) +foreign import ccall unsafe "libmounts.h mounts_next" c_mounts_next + :: Ptr () -> IO (Ptr ()) -foreign import ccall safe "getmntent" - c_getmntent :: ((Ptr ()) -> (IO (Ptr ()))) +foreign import ccall unsafe "libmounts.h mounts_end" c_mounts_end + :: Ptr () -> IO CInt diff --git a/Utility/libmounts.c b/Utility/libmounts.c new file mode 100644 index 000000000..00755c577 --- /dev/null +++ b/Utility/libmounts.c @@ -0,0 +1,105 @@ +/* mounted filesystems, C mini-library + * + * Copyright (c) 1980, 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2001 + * David Rufino <daverufino@btinternet.com> + * Copyright 2012 + * Joey Hess <joey@kitenet.net> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "libmounts.h" + +#include <errno.h> +#include <stdio.h> + +#ifdef GETMNTENT +/* direct passthrough the getmntent */ +FILE *mounts_start (void) { + return setmntent("/etc/mtab", "r"); +} +int mounts_end (FILE *fp) { + return endmntent(fp); +} +struct mntent *mounts_next (FILE *fp) { + return getmntent(fp); +} +#endif + +#ifdef GETMNTINFOCALL +/* getmntent emulation using getmntinfo */ +FILE *mounts_start (void) { + return ((FILE *)0x1) /* dummy non-NULL FILE pointer, not used */ +} +int mounts_end (FILE *fp) { + return 1; +} + +static struct mntent _mntent; + +static struct mntent *statfs_to_mntent (struct MNTINFOSTRUCT *mntbuf) { + _mntent.mnt_fsname = mntbuf->f_mntfromname; + _mntent.mnt_dir = mntbuf->f_mntonname; + _mntent.mnt_type = mntbuf->f_fstypename; + + _mntent.mnt_opts = '\0'; + _mntent.mnt_freq = 0; + _mntent.mnt_passno = 0; + + return (&_mntent); +} + +static int pos = -1; +static int mntsize = -1; + +struct mntent *mounts_next (FILE *fp) { + struct MNTINFOSTRUCT *mntbuf; + + if (pos == -1 || mntsize == -1) + mntsize = GETMNTINFOCALL(&mntbuf, MNT_NOWAIT); + ++pos; + if (pos == mntsize) { + pos = mntsize = -1; + return NULL; + } + + return (statfs_to_mntent(&mntbuf[pos])); +} +#endif + +#ifdef UNKNOWN +/* dummy, do-nothing version */ +FILE *mounts_start (void) { + return ((FILE *)0x1); +} +int mounts_end (FILE *fp) { + return 1; +} +struct mntent *mounts_next (FILE *fp) { + return NULL; +} +#endif diff --git a/Utility/libmounts.h b/Utility/libmounts.h new file mode 100644 index 000000000..0bd52e323 --- /dev/null +++ b/Utility/libmounts.h @@ -0,0 +1,48 @@ +/* Include appropriate headers for the OS, and define what will be used. */ +#if defined(__APPLE__) +# include <sys/param.h> +# include <sys/ucred.h> +# include <sys/mount.h> +/* In newer OSX versions, statfs64 is deprecated, in favor of statfs, + * which is 64 bit only with a build option -- but statfs64 still works, + * and this keeps older OSX also supported. */ +# define GETMNTINFOCALL getmntinfo64 +# define MNTINFOSTRUCT statfs64 +#else +#if defined (__FreeBSD__) +# include <sys/param.h> +# include <sys/ucred.h> +# include <sys/mount.h> +# define GETMNTINFOCALL getmntinfo64 +# define MNTINFOSTRUCT statfs64 +#else +#if defined (__linux__) || defined (__FreeBSD_kernel__) +/* Linux or Debian kFreeBSD */ +#include <mntent.h> +# define GETMNTENT +#else +# warning mounts listing code not available for this OS +# define UNKNOWN +#endif +#endif +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#ifndef GETMNTENT +#warning "boo" +struct mntent { + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; /* not filled in */ + int mnt_freq; /* not filled in */ + int mnt_passno; /* not filled in */ +}; +#endif + +FILE *mounts_start (void); +int mounts_end (FILE *fp); +struct mntent *mounts_next (FILE *fp); diff --git a/debian/copyright b/debian/copyright index dcfbaf3e3..26a559cc5 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,13 +8,22 @@ License: GPL-3+ this package's source, or in /usr/share/common-licenses/GPL-3 on Debian systems. -Files: Utility/Mtab.hcs +Files: Utility/Mounts.hsc Copyright: Volker Wysk <hsss@volker-wysk.de> License: LGPL-2.1+ - the full text of version 2.1 of the LGPL is distributed as doc/LGPL + The full text of version 2.1 of the LGPL is distributed as doc/LGPL in this package's source, or in /usr/share/common-licences/LGPL-2.1 on Debian systems. +Files: Utility/libmounts.c +Copyright: 1980, 1989, 1993, 1994 The Regents of the University of California + 2001 David Rufino <daverufino@btinternet.com> + 2012 Joey Hess <joey@kitenet.net> +License: BSD-3-clause + The full test of the 3 clause BSD license is distributed inside + Utility/libmounts.c in this package's source, or in + /usr/share/common-licenses/BSD on Debian systems. + Files: doc/logo.png doc/logo_small.png doc/favicon.png Copyright: 2007 Henrik Nyh <http://henrik.nyh.se/> 2010 Joey Hess <joey@kitenet.net> diff --git a/git-annex.cabal b/git-annex.cabal index 00f57319d..be752f844 100644 --- a/git-annex.cabal +++ b/git-annex.cabal @@ -46,7 +46,7 @@ Executable git-annex IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance, process -- Need to list these because they're generated from .hsc files. Other-Modules: Utility.Touch Utility.Mounts - C-Sources: Utility/libdiskfree.c + C-Sources: Utility/libdiskfree.c Utility/libmounts.c Extensions: CPP GHC-Options: -threaded |