diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,10 @@
+Copyright (c) 2009, Matthew Elder <matt@mattelder.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * 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.
+    * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,7 @@
+module Main (main) where
+
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMain
+
diff --git a/csrc/sendfile_linux.c b/csrc/sendfile_linux.c
new file mode 100644
--- /dev/null
+++ b/csrc/sendfile_linux.c
@@ -0,0 +1,34 @@
+
+/* LINUX */
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
+
+/* return value is system error code */
+int c_sendfile_linux(int out_fd, char* in_fp) {
+    int in_fd;
+    struct stat in_stat;
+
+    in_fd = open(in_fp, O_RDONLY);
+    if(in_fd == -1) {
+        return errno;
+    }
+
+    if(fstat(in_fd, &in_stat) == -1) {
+        return errno;
+    }
+
+    if(sendfile(out_fd, in_fd, NULL, in_stat.st_size) == -1) {
+        return errno;
+    }
+
+    if(close(in_fd) == -1) {
+        return errno;
+    }
+    
+    /* if no errors, return 0 to indicate no errors */
+    return 0;
+}
+
diff --git a/csrc/sendfile_win32.c b/csrc/sendfile_win32.c
new file mode 100644
--- /dev/null
+++ b/csrc/sendfile_win32.c
@@ -0,0 +1,34 @@
+
+/* WIN32 */
+#include <windows.h>
+#include <mswsock.h>
+
+/* return value is system error code defined here:
+ * http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx
+ */
+int c_sendfile_win32(int out_fd, char* in_fp) {
+    HANDLE in_hdl =
+        CreateFile(
+          in_fp,
+          GENERIC_READ,
+          FILE_SHARE_READ,
+          NULL,
+          OPEN_EXISTING,
+          FILE_FLAG_SEQUENTIAL_SCAN,
+          NULL
+        );
+    if(in_hdl == INVALID_HANDLE_VALUE) {
+        return GetLastError();
+    }
+    
+    if(! TransmitFile(out_fd, in_hdl, 0, 0, NULL, NULL, TF_USE_KERNEL_APC)) {
+        return WSAGetLastError();
+    }
+    
+    if(! CloseHandle(in_hdl)) {
+        return GetLastError();
+    }
+    
+    /* if no errors, return 0 to indicate no errors */
+    return 0;
+}
diff --git a/sendfile.cabal b/sendfile.cabal
new file mode 100644
--- /dev/null
+++ b/sendfile.cabal
@@ -0,0 +1,46 @@
+name:          sendfile
+version:       0.1
+stability:     experimental
+synopsis:      A portable sendfile library
+description:   A library which exposes zero-copy sendfile functionality in a portable way. If a platform does not support sendfile, a fallback implementation in haskell is provided.
+license:       BSD3
+license-file:  LICENSE
+author:        Matthew Elder <matt@mattelder.org>
+maintainer:    Matthew Elder <matt@mattelder.org>
+homepage:      http://patch-tag.com/r/sendfile
+category:      Network
+build-type:    Simple
+cabal-version: >= 1.6
+
+flag portable
+    description: Explicitly enable portable sendfile support (implemented in Haskell)
+    default:     False
+
+library
+    hs-source-dirs:  src
+
+    exposed-modules: SendFile
+                     SendFile.Internal
+    
+    build-depends:   base >= 3 && < 5,
+                     bytestring >= 0.9.1.4 && < 0.10,
+                     network >= 2 && < 3
+    
+    if flag(portable)
+      cc-options: -DPORTABLE_SENDFILE
+    else
+      if os(windows)
+        cc-options: -DWIN32_SENDFILE
+        c-sources: csrc/sendfile_win32.c
+        extra-libraries: kernel32, mswsock
+      else
+        if os(linux)
+          cc-options: -DLINUX_SENDFILE
+          c-sources: csrc/sendfile_linux.c
+        else
+          cc-options: -DPORTABLE_SENDFILE
+
+source-repository head
+    type:     darcs
+    location: http://patch-tag.com/r/sendfile/pullrepo
+
diff --git a/src/SendFile.hs b/src/SendFile.hs
new file mode 100644
--- /dev/null
+++ b/src/SendFile.hs
@@ -0,0 +1,17 @@
+module SendFile (
+    sendFile,
+    sendFileMode
+    ) where
+    
+import qualified SendFile.Internal
+import System.IO (Handle(..))
+
+-- | A cross-platform wrapper for sendfile -- this implements an available operating-system call if supported, otherwise it falls back to a portable haskell implementation. It takes a Handle which it will first flush before handing it to the operating system to perform the transmission.
+sendFile :: Handle   -- ^ The output Handle
+         -> FilePath -- ^ The path where the input file resides
+         -> IO ()  -- ^ Whether or not the transmission was successful
+sendFile = SendFile.Internal.sendFile
+
+-- | Returns the mode that sendfile was compiled with. Mainly for debugging use. Possible values are 'WIN32_SENDFILE' and 'PORTABLE_SENDFILE'.
+sendFileMode :: String -- ^ The mode that sendfile was compiled with
+sendFileMode = SendFile.Internal.sendFileMode
diff --git a/src/SendFile/Internal.hsc b/src/SendFile/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/SendFile/Internal.hsc
@@ -0,0 +1,67 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+module SendFile.Internal (
+    sendFile,
+    sendFileMode
+    ) where
+    
+import Data.ByteString.Char8
+import Prelude hiding (readFile)
+import System.IO (Handle(..), hFlush)
+
+#if defined(WIN32_SENDFILE) && !defined(PORTABLE_SENDFILE)
+import Foreign.C
+import GHC.IOBase (haFD)
+import GHC.Handle (withHandle_)
+
+sendFileMode :: String
+sendFileMode = "WIN32_SENDFILE"
+
+sendFile :: Handle -> FilePath -> IO ()
+sendFile outh infp = do
+    -- flush outh before handing it sendFile
+    hFlush outh
+    withHandle_ "sendFile" outh $ \outh' -> do 
+    withCString infp $ \in_fp -> do
+    let out_fd = haFD outh'
+    err <- c_sendfile_win32 out_fd in_fp
+    if err == 0
+        then return ()
+        else fail ("system error " ++ show err)
+    
+foreign import ccall
+    c_sendfile_win32 :: CInt -> CString -> IO Int
+#else
+#  if defined(LINUX_SENDFILE) && !defined(PORTABLE_SENDFILE)
+import Foreign.C
+import GHC.IOBase (haFD)
+import GHC.Handle (withHandle_)
+
+sendFileMode :: String
+sendFileMode = "LINUX_SENDFILE"
+
+sendFile :: Handle -> FilePath -> IO ()
+sendFile outh infp = do
+    -- flush outh before handing it sendFile
+    hFlush outh
+    withHandle_ "sendFile" outh $ \outh' -> do 
+    withCString infp $ \in_fp -> do
+    let out_fd = haFD outh'
+    err <- c_sendfile_linux out_fd in_fp
+    if err == 0
+        then return ()
+        else fail ("errno " ++ show err)
+    
+foreign import ccall
+    c_sendfile_linux :: CInt -> CString -> IO Int
+#  else
+sendFileMode :: String
+sendFileMode = "PORTABLE_SENDFILE"
+
+-- FIXME: possibly immature / inefficient implementation
+sendFile :: Handle -> FilePath -> IO ()
+sendFile outh infp = do
+    hPutStr outh =<< readFile infp
+    return ()
+#  endif
+#endif
+
