aboutsummaryrefslogtreecommitdiff
path: root/Command/TransferInfo.hs
blob: 8ab577a81b005f01467ea43d9cfd54820d82a16b (plain)
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
{- git-annex command
 -
 - Copyright 2012 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Command.TransferInfo where

import Common.Annex
import Command
import Annex.Content
import Logs.Transfer
import Types.Key
import qualified CmdLine.GitAnnexShell.Fields as Fields
import Utility.Metered

def :: [Command]
def = [noCommit $ command "transferinfo" paramKey seek SectionPlumbing
	"updates sender on number of bytes of content received"]

seek :: CommandSeek
seek = withWords start

{- Security:
 - 
 - The transfer info file contains the user-supplied key, but
 - the built-in guards prevent slashes in it from showing up in the filename.
 - It also contains the UUID of the remote. But slashes are also filtered
 - out of that when generating the filename.
 - 
 - Checks that the key being transferred is inAnnex, to prevent
 - malicious spamming of bogus keys. Does not check that a transfer
 - of the key is actually in progress, because this could be started
 - concurrently with sendkey, and win the race.
 -}
start :: [String] -> CommandStart
start (k:[]) = do
	case file2key k of
		Nothing -> error "bad key"
		(Just key) -> whenM (inAnnex key) $ do
			file <- Fields.getField Fields.associatedFile
			u <- maybe (error "missing remoteuuid") toUUID
				<$> Fields.getField Fields.remoteUUID
			let t = Transfer
				{ transferDirection = Upload
				, transferUUID = u
				, transferKey = key
				}
			info <- liftIO $ startTransferInfo file
			(update, tfile, _) <- mkProgressUpdater t info
			liftIO $ mapM_ void
				[ tryIO $ forever $ do
					bytes <- readUpdate
					maybe (error "transferinfo protocol error")
						(update . toBytesProcessed) bytes
				, tryIO $ removeFile tfile
				, exitSuccess
				]
	stop
start _ = error "wrong number of parameters"

readUpdate :: IO (Maybe Integer)
readUpdate = readish <$> getLine