2018-04-20 10:33:50 +00:00
package hashsum
import (
2019-06-17 08:34:30 +00:00
"context"
2021-11-04 10:12:57 +00:00
"errors"
2018-04-20 10:33:50 +00:00
"fmt"
"os"
2019-07-28 17:47:38 +00:00
"github.com/rclone/rclone/cmd"
2020-12-18 12:45:58 +00:00
"github.com/rclone/rclone/fs"
2019-10-26 19:27:33 +00:00
"github.com/rclone/rclone/fs/config/flags"
2019-07-28 17:47:38 +00:00
"github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/fs/operations"
2018-04-20 10:33:50 +00:00
"github.com/spf13/cobra"
2020-12-18 12:45:58 +00:00
"github.com/spf13/pflag"
2018-04-20 10:33:50 +00:00
)
2021-05-18 09:27:17 +00:00
// Global hashsum flags for reuse in hashsum, md5sum, sha1sum
2019-10-26 19:27:33 +00:00
var (
2020-12-18 12:45:58 +00:00
OutputBase64 = false
DownloadFlag = false
HashsumOutfile = ""
2021-07-07 15:34:16 +00:00
ChecksumFile = ""
2019-10-26 19:27:33 +00:00
)
2018-04-20 10:33:50 +00:00
func init ( ) {
cmd . Root . AddCommand ( commandDefinition )
2019-10-26 19:27:33 +00:00
cmdFlags := commandDefinition . Flags ( )
2020-12-18 12:45:58 +00:00
AddHashFlags ( cmdFlags )
}
2021-05-18 09:27:17 +00:00
// AddHashFlags is a convenience function to add the command flags OutputBase64 and DownloadFlag to hashsum, md5sum, sha1sum
2020-12-18 12:45:58 +00:00
func AddHashFlags ( cmdFlags * pflag . FlagSet ) {
flags . BoolVarP ( cmdFlags , & OutputBase64 , "base64" , "" , OutputBase64 , "Output base64 encoded hashsum" )
flags . StringVarP ( cmdFlags , & HashsumOutfile , "output-file" , "" , HashsumOutfile , "Output hashsums to a file rather than the terminal" )
2021-07-07 15:34:16 +00:00
flags . StringVarP ( cmdFlags , & ChecksumFile , "checkfile" , "C" , ChecksumFile , "Validate hashes against a given SUM file instead of printing them" )
2020-12-18 12:45:58 +00:00
flags . BoolVarP ( cmdFlags , & DownloadFlag , "download" , "" , DownloadFlag , "Download the file and hash it locally; if this flag is not specified, the hash is requested from the remote" )
}
// GetHashsumOutput opens and closes the output file when using the output-file flag
func GetHashsumOutput ( filename string ) ( out * os . File , close func ( ) , err error ) {
out , err = os . Create ( filename )
if err != nil {
2021-11-04 10:12:57 +00:00
err = fmt . Errorf ( "Failed to open output file %v: %w" , filename , err )
2020-12-18 12:45:58 +00:00
return nil , nil , err
}
close = func ( ) {
err := out . Close ( )
if err != nil {
fs . Errorf ( nil , "Failed to close output file %v: %v" , filename , err )
}
}
return out , close , nil
2018-04-20 10:33:50 +00:00
}
var commandDefinition = & cobra . Command {
Use : "hashsum <hash> remote:path" ,
2020-05-19 11:02:44 +00:00
Short : ` Produces a hashsum file for all the objects in the path. ` ,
2018-04-20 10:33:50 +00:00
Long : `
Produces a hash file for all the objects in the path using the hash
named . The output is in the same format as the standard
md5sum / sha1sum tool .
2020-12-18 12:45:58 +00:00
By default , the hash is requested from the remote . If the hash is
not supported by the remote , no hash will be returned . With the
download flag , the file will be downloaded from the remote and
hashed locally enabling any hash for any remote .
Run without a hash to see the list of all supported hashes , e . g .
2018-04-20 10:33:50 +00:00
$ rclone hashsum
2021-07-07 15:34:16 +00:00
` + hash.HelpString(4) + `
2018-04-20 10:33:50 +00:00
Then
$ rclone hashsum MD5 remote : path
2021-05-21 14:32:33 +00:00
2021-10-13 12:02:49 +00:00
Note that hash names are case insensitive and values are output in lower case .
2018-04-20 10:33:50 +00:00
` ,
RunE : func ( command * cobra . Command , args [ ] string ) error {
cmd . CheckArgs ( 0 , 2 , command , args )
if len ( args ) == 0 {
2021-07-07 15:34:16 +00:00
fmt . Print ( hash . HelpString ( 0 ) )
2018-04-20 10:33:50 +00:00
return nil
} else if len ( args ) == 1 {
return errors . New ( "need hash type and remote" )
}
var ht hash . Type
err := ht . Set ( args [ 0 ] )
if err != nil {
2021-07-07 15:34:16 +00:00
fmt . Println ( hash . HelpString ( 0 ) )
2018-04-20 10:33:50 +00:00
return err
}
fsrc := cmd . NewFsSrc ( args [ 1 : ] )
2020-12-18 12:45:58 +00:00
2018-04-20 10:33:50 +00:00
cmd . Run ( false , false , command , func ( ) error {
2021-07-07 15:34:16 +00:00
if ChecksumFile != "" {
fsum , sumFile := cmd . NewFsFile ( ChecksumFile )
return operations . CheckSum ( context . Background ( ) , fsrc , fsum , sumFile , ht , nil , DownloadFlag )
}
2020-12-18 12:45:58 +00:00
if HashsumOutfile == "" {
return operations . HashLister ( context . Background ( ) , ht , OutputBase64 , DownloadFlag , fsrc , nil )
}
output , close , err := GetHashsumOutput ( HashsumOutfile )
if err != nil {
return err
2019-10-26 19:27:33 +00:00
}
2020-12-18 12:45:58 +00:00
defer close ( )
return operations . HashLister ( context . Background ( ) , ht , OutputBase64 , DownloadFlag , fsrc , output )
2018-04-20 10:33:50 +00:00
} )
return nil
} ,
}