2010-12-31 17:39:30 +00:00
|
|
|
{- git-annex command
|
|
|
|
-
|
|
|
|
- Copyright 2010 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module Command.RecvKey where
|
|
|
|
|
2013-05-11 20:03:00 +00:00
|
|
|
import System.PosixCompat.Files
|
|
|
|
|
2011-10-05 20:02:51 +00:00
|
|
|
import Common.Annex
|
2010-12-31 17:39:30 +00:00
|
|
|
import Command
|
2011-01-16 20:05:05 +00:00
|
|
|
import CmdLine
|
2011-10-04 04:40:47 +00:00
|
|
|
import Annex.Content
|
2013-03-29 00:34:07 +00:00
|
|
|
import Annex
|
2012-09-19 18:28:32 +00:00
|
|
|
import Utility.Rsync
|
2012-07-02 05:31:10 +00:00
|
|
|
import Logs.Transfer
|
2012-08-23 19:22:23 +00:00
|
|
|
import Command.SendKey (fieldTransfer)
|
2013-01-11 19:43:09 +00:00
|
|
|
import qualified Fields
|
|
|
|
import qualified Types.Key
|
|
|
|
import qualified Types.Backend
|
|
|
|
import qualified Backend
|
2010-12-31 17:39:30 +00:00
|
|
|
|
2011-10-29 19:19:05 +00:00
|
|
|
def :: [Command]
|
2012-09-16 00:46:38 +00:00
|
|
|
def = [noCommit $ command "recvkey" paramKey seek
|
2013-03-24 22:28:21 +00:00
|
|
|
SectionPlumbing "runs rsync in server mode to receive content"]
|
2010-12-31 17:39:30 +00:00
|
|
|
|
|
|
|
seek :: [CommandSeek]
|
|
|
|
seek = [withKeys start]
|
|
|
|
|
2011-09-15 20:50:49 +00:00
|
|
|
start :: Key -> CommandStart
|
2012-07-02 05:31:10 +00:00
|
|
|
start key = ifM (inAnnex key)
|
|
|
|
( error "key is already present in annex"
|
2013-09-25 07:09:06 +00:00
|
|
|
, fieldTransfer Download key $ \_p ->
|
2013-01-11 19:43:09 +00:00
|
|
|
ifM (getViaTmp key go)
|
2012-07-02 05:31:10 +00:00
|
|
|
( do
|
|
|
|
-- forcibly quit after receiving one key,
|
|
|
|
-- and shutdown cleanly
|
|
|
|
_ <- shutdown True
|
2012-08-23 19:22:23 +00:00
|
|
|
return True
|
|
|
|
, return False
|
2012-07-02 05:31:10 +00:00
|
|
|
)
|
|
|
|
)
|
2013-01-11 19:43:09 +00:00
|
|
|
where
|
2013-03-29 00:34:07 +00:00
|
|
|
go tmp = do
|
2013-03-30 23:05:51 +00:00
|
|
|
opts <- filterRsyncSafeOptions . maybe [] words
|
|
|
|
<$> getField "RsyncOptions"
|
2013-05-06 21:30:57 +00:00
|
|
|
ok <- liftIO $ rsyncServerReceive (map Param opts) tmp
|
|
|
|
|
|
|
|
-- The file could have been received with permissions that
|
|
|
|
-- do not allow reading it, so this is done before the
|
|
|
|
-- directcheck.
|
|
|
|
freezeContent tmp
|
|
|
|
|
|
|
|
if ok
|
|
|
|
then ifM (isJust <$> Fields.getField Fields.direct)
|
2013-03-29 00:34:07 +00:00
|
|
|
( directcheck tmp
|
|
|
|
, return True
|
|
|
|
)
|
2013-05-06 21:30:57 +00:00
|
|
|
else return False
|
2013-01-11 19:43:09 +00:00
|
|
|
{- If the sending repository uses direct mode, the file
|
|
|
|
- it sends could be modified as it's sending it. So check
|
|
|
|
- that the right size file was received, and that the key/value
|
|
|
|
- Backend is happy with it. -}
|
|
|
|
directcheck tmp = do
|
|
|
|
oksize <- case Types.Key.keySize key of
|
|
|
|
Nothing -> return True
|
|
|
|
Just size -> do
|
|
|
|
size' <- fromIntegral . fileSize
|
|
|
|
<$> liftIO (getFileStatus tmp)
|
|
|
|
return $ size == size'
|
|
|
|
if oksize
|
|
|
|
then case Backend.maybeLookupBackendName (Types.Key.keyBackendName key) of
|
2013-10-01 18:10:45 +00:00
|
|
|
Nothing -> do
|
|
|
|
warning "recvkey: received key from direct mode repository using unknown backend; cannot check; discarding"
|
|
|
|
return False
|
|
|
|
Just backend -> maybe (return True) runfsck
|
2013-01-11 19:43:09 +00:00
|
|
|
(Types.Backend.fsckKey backend)
|
2013-10-01 18:10:45 +00:00
|
|
|
else do
|
|
|
|
warning "recvkey: received key with wrong size; discarding"
|
|
|
|
return False
|
|
|
|
where
|
|
|
|
runfsck check = ifM (check key tmp)
|
|
|
|
( return True
|
|
|
|
, do
|
|
|
|
warning "recvkey: received key from direct mode repository seems to have changed as it was transferred; discarding"
|
|
|
|
return False
|
|
|
|
)
|