2018-01-13 00:30:54 +08:00
// Package configflags defines the flags used by rclone. It is
// decoupled into a separate package so it can be replaced.
package configflags
// Options set by command line flags
import (
"log"
"net"
2021-09-10 20:44:13 +08:00
"os"
2021-01-29 11:41:50 +08:00
"strconv"
2018-01-13 00:30:54 +08:00
"strings"
2019-07-29 01:47:38 +08:00
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
"github.com/rclone/rclone/fs/config/flags"
fsLog "github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/rc"
2019-07-26 08:54:09 +08:00
"github.com/sirupsen/logrus"
2018-01-13 00:30:54 +08:00
"github.com/spf13/pflag"
)
var (
// these will get interpreted into fs.Config via SetFlags() below
2020-02-26 01:03:21 +08:00
verbose int
quiet bool
2021-04-08 23:49:47 +08:00
configPath string
2021-09-10 21:35:53 +08:00
cacheDir string
2021-09-10 20:44:13 +08:00
tempDir string
2020-02-26 01:03:21 +08:00
dumpHeaders bool
dumpBodies bool
deleteBefore bool
deleteDuring bool
deleteAfter bool
bindAddr string
disableFeatures string
2021-01-29 11:41:50 +08:00
dscp string
2020-02-10 15:50:08 +08:00
uploadHeaders [ ] string
downloadHeaders [ ] string
2020-04-23 22:24:21 +08:00
headers [ ] string
2022-05-24 22:46:07 +08:00
metadataSet [ ] string
2018-01-13 00:30:54 +08:00
)
// AddFlags adds the non filing system specific flags to the command
2020-11-05 19:33:32 +08:00
func AddFlags ( ci * fs . ConfigInfo , flagSet * pflag . FlagSet ) {
rc . AddOption ( "main" , ci )
2018-01-13 00:30:54 +08:00
// NB defaults which aren't the zero for the type should be set in fs/config.go NewConfig
flags . CountVarP ( flagSet , & verbose , "verbose" , "v" , "Print lots more stuff (repeat for more)" )
flags . BoolVarP ( flagSet , & quiet , "quiet" , "q" , false , "Print as little stuff as possible" )
2020-11-05 19:33:32 +08:00
flags . DurationVarP ( flagSet , & ci . ModifyWindow , "modify-window" , "" , ci . ModifyWindow , "Max time diff to be considered the same" )
2021-08-16 17:30:01 +08:00
flags . IntVarP ( flagSet , & ci . Checkers , "checkers" , "" , ci . Checkers , "Number of checkers to run in parallel" )
flags . IntVarP ( flagSet , & ci . Transfers , "transfers" , "" , ci . Transfers , "Number of file transfers to run in parallel" )
flags . StringVarP ( flagSet , & configPath , "config" , "" , config . GetConfigPath ( ) , "Config file" )
flags . StringVarP ( flagSet , & cacheDir , "cache-dir" , "" , config . GetCacheDir ( ) , "Directory rclone will use for caching" )
flags . StringVarP ( flagSet , & tempDir , "temp-dir" , "" , os . TempDir ( ) , "Directory rclone will use for temporary files" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . CheckSum , "checksum" , "c" , ci . CheckSum , "Skip based on checksum (if available) & size, not mod-time & size" )
flags . BoolVarP ( flagSet , & ci . SizeOnly , "size-only" , "" , ci . SizeOnly , "Skip based on size only, not mod-time or checksum" )
flags . BoolVarP ( flagSet , & ci . IgnoreTimes , "ignore-times" , "I" , ci . IgnoreTimes , "Don't skip files that match size and time - transfer all files" )
flags . BoolVarP ( flagSet , & ci . IgnoreExisting , "ignore-existing" , "" , ci . IgnoreExisting , "Skip all files that exist on destination" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . IgnoreErrors , "ignore-errors" , "" , ci . IgnoreErrors , "Delete even if there are I/O errors" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . DryRun , "dry-run" , "n" , ci . DryRun , "Do a trial run with no permanent changes" )
flags . BoolVarP ( flagSet , & ci . Interactive , "interactive" , "i" , ci . Interactive , "Enable interactive mode" )
flags . DurationVarP ( flagSet , & ci . ConnectTimeout , "contimeout" , "" , ci . ConnectTimeout , "Connect timeout" )
flags . DurationVarP ( flagSet , & ci . Timeout , "timeout" , "" , ci . Timeout , "IO idle timeout" )
flags . DurationVarP ( flagSet , & ci . ExpectContinueTimeout , "expect-continue-timeout" , "" , ci . ExpectContinueTimeout , "Timeout when using expect / 100-continue in HTTP" )
2019-05-09 12:06:24 +08:00
flags . BoolVarP ( flagSet , & dumpHeaders , "dump-headers" , "" , false , "Dump HTTP headers - may contain sensitive info" )
2018-01-13 00:30:54 +08:00
flags . BoolVarP ( flagSet , & dumpBodies , "dump-bodies" , "" , false , "Dump HTTP headers and bodies - may contain sensitive info" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . InsecureSkipVerify , "no-check-certificate" , "" , ci . InsecureSkipVerify , "Do not verify the server SSL certificate (insecure)" )
flags . BoolVarP ( flagSet , & ci . AskPassword , "ask-password" , "" , ci . AskPassword , "Allow prompt for password for encrypted configuration" )
flags . FVarP ( flagSet , & ci . PasswordCommand , "password-command" , "" , "Command for supplying password for encrypted configuration" )
2018-11-15 00:11:58 +08:00
flags . BoolVarP ( flagSet , & deleteBefore , "delete-before" , "" , false , "When synchronizing, delete files on destination before transferring" )
2018-07-19 02:30:14 +08:00
flags . BoolVarP ( flagSet , & deleteDuring , "delete-during" , "" , false , "When synchronizing, delete files during transfer" )
2018-11-15 00:11:58 +08:00
flags . BoolVarP ( flagSet , & deleteAfter , "delete-after" , "" , false , "When synchronizing, delete files on destination after transferring (default)" )
2020-11-05 19:33:32 +08:00
flags . Int64VarP ( flagSet , & ci . MaxDelete , "max-delete" , "" , - 1 , "When synchronizing, limit the number of deletes" )
2022-08-03 22:53:02 +08:00
flags . FVarP ( flagSet , & ci . MaxDeleteSize , "max-delete-size" , "" , "When synchronizing, limit the total size of deletes" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . TrackRenames , "track-renames" , "" , ci . TrackRenames , "When synchronizing, track file renames and do a server-side move if possible" )
flags . StringVarP ( flagSet , & ci . TrackRenamesStrategy , "track-renames-strategy" , "" , ci . TrackRenamesStrategy , "Strategies to use when synchronizing using track-renames hash|modtime|leaf" )
2021-08-16 17:30:01 +08:00
flags . IntVarP ( flagSet , & ci . LowLevelRetries , "low-level-retries" , "" , ci . LowLevelRetries , "Number of low level retries to do" )
flags . BoolVarP ( flagSet , & ci . UpdateOlder , "update" , "u" , ci . UpdateOlder , "Skip files that are newer on the destination" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . UseServerModTime , "use-server-modtime" , "" , ci . UseServerModTime , "Use server modified time instead of object metadata" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . NoGzip , "no-gzip-encoding" , "" , ci . NoGzip , "Don't set Accept-Encoding: gzip" )
flags . IntVarP ( flagSet , & ci . MaxDepth , "max-depth" , "" , ci . MaxDepth , "If set limits the recursion depth to this" )
flags . BoolVarP ( flagSet , & ci . IgnoreSize , "ignore-size" , "" , false , "Ignore size when skipping use mod-time or checksum" )
flags . BoolVarP ( flagSet , & ci . IgnoreChecksum , "ignore-checksum" , "" , ci . IgnoreChecksum , "Skip post copy check of checksums" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . IgnoreCaseSync , "ignore-case-sync" , "" , ci . IgnoreCaseSync , "Ignore case when synchronizing" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . NoTraverse , "no-traverse" , "" , ci . NoTraverse , "Don't traverse destination file system on copy" )
flags . BoolVarP ( flagSet , & ci . CheckFirst , "check-first" , "" , ci . CheckFirst , "Do all the checks before starting transfers" )
flags . BoolVarP ( flagSet , & ci . NoCheckDest , "no-check-dest" , "" , ci . NoCheckDest , "Don't check the destination, copy regardless" )
flags . BoolVarP ( flagSet , & ci . NoUnicodeNormalization , "no-unicode-normalization" , "" , ci . NoUnicodeNormalization , "Don't normalize unicode characters in filenames" )
flags . BoolVarP ( flagSet , & ci . NoUpdateModTime , "no-update-modtime" , "" , ci . NoUpdateModTime , "Don't update destination mod-time if files identical" )
flags . StringArrayVarP ( flagSet , & ci . CompareDest , "compare-dest" , "" , nil , "Include additional comma separated server-side paths during comparison" )
flags . StringArrayVarP ( flagSet , & ci . CopyDest , "copy-dest" , "" , nil , "Implies --compare-dest but also copies files from paths into destination" )
flags . StringVarP ( flagSet , & ci . BackupDir , "backup-dir" , "" , ci . BackupDir , "Make backups into hierarchy based in DIR" )
flags . StringVarP ( flagSet , & ci . Suffix , "suffix" , "" , ci . Suffix , "Suffix to add to changed files" )
flags . BoolVarP ( flagSet , & ci . SuffixKeepExtension , "suffix-keep-extension" , "" , ci . SuffixKeepExtension , "Preserve the extension when using --suffix" )
flags . BoolVarP ( flagSet , & ci . UseListR , "fast-list" , "" , ci . UseListR , "Use recursive list if available; uses more memory but fewer transactions" )
flags . Float64VarP ( flagSet , & ci . TPSLimit , "tpslimit" , "" , ci . TPSLimit , "Limit HTTP transactions per second to this" )
flags . IntVarP ( flagSet , & ci . TPSLimitBurst , "tpslimit-burst" , "" , ci . TPSLimitBurst , "Max burst of transactions for --tpslimit" )
flags . StringVarP ( flagSet , & bindAddr , "bind" , "" , "" , "Local address to bind to for outgoing connections, IPv4, IPv6 or name" )
flags . StringVarP ( flagSet , & disableFeatures , "disable" , "" , "" , "Disable a comma separated list of features (use --disable help to see a list)" )
flags . StringVarP ( flagSet , & ci . UserAgent , "user-agent" , "" , ci . UserAgent , "Set the user-agent to a specified string" )
flags . BoolVarP ( flagSet , & ci . Immutable , "immutable" , "" , ci . Immutable , "Do not modify files, fail if existing files have been modified" )
flags . BoolVarP ( flagSet , & ci . AutoConfirm , "auto-confirm" , "" , ci . AutoConfirm , "If enabled, do not request console confirmation" )
flags . IntVarP ( flagSet , & ci . StatsFileNameLength , "stats-file-name-length" , "" , ci . StatsFileNameLength , "Max file name length in stats (0 for no limit)" )
2020-11-05 19:33:32 +08:00
flags . FVarP ( flagSet , & ci . LogLevel , "log-level" , "" , "Log level DEBUG|INFO|NOTICE|ERROR" )
flags . FVarP ( flagSet , & ci . StatsLogLevel , "stats-log-level" , "" , "Log level to show --stats output DEBUG|INFO|NOTICE|ERROR" )
2021-08-16 17:30:01 +08:00
flags . FVarP ( flagSet , & ci . BwLimit , "bwlimit" , "" , "Bandwidth limit in KiB/s, or use suffix B|K|M|G|T|P or a full timetable" )
flags . FVarP ( flagSet , & ci . BwLimitFile , "bwlimit-file" , "" , "Bandwidth limit per file in KiB/s, or use suffix B|K|M|G|T|P or a full timetable" )
flags . FVarP ( flagSet , & ci . BufferSize , "buffer-size" , "" , "In memory buffer size when reading files for each --transfer" )
flags . FVarP ( flagSet , & ci . StreamingUploadCutoff , "streaming-upload-cutoff" , "" , "Cutoff for switching to chunked upload if file size is unknown, upload starts after reaching cutoff or when file ends" )
2020-11-05 19:33:32 +08:00
flags . FVarP ( flagSet , & ci . Dump , "dump" , "" , "List of items to dump from: " + fs . DumpFlagsList )
2021-08-16 17:30:01 +08:00
flags . FVarP ( flagSet , & ci . MaxTransfer , "max-transfer" , "" , "Maximum size of data to transfer" )
flags . DurationVarP ( flagSet , & ci . MaxDuration , "max-duration" , "" , 0 , "Maximum duration rclone will transfer data for" )
2020-11-05 19:33:32 +08:00
flags . FVarP ( flagSet , & ci . CutoffMode , "cutoff-mode" , "" , "Mode to stop transfers when reaching the max transfer limit HARD|SOFT|CAUTIOUS" )
2021-08-16 17:30:01 +08:00
flags . IntVarP ( flagSet , & ci . MaxBacklog , "max-backlog" , "" , ci . MaxBacklog , "Maximum number of objects in sync or check backlog" )
flags . IntVarP ( flagSet , & ci . MaxStatsGroups , "max-stats-groups" , "" , ci . MaxStatsGroups , "Maximum number of stats groups to keep in memory, on max oldest is discarded" )
flags . BoolVarP ( flagSet , & ci . StatsOneLine , "stats-one-line" , "" , ci . StatsOneLine , "Make the stats fit on one line" )
flags . BoolVarP ( flagSet , & ci . StatsOneLineDate , "stats-one-line-date" , "" , ci . StatsOneLineDate , "Enable --stats-one-line and add current date/time prefix" )
flags . StringVarP ( flagSet , & ci . StatsOneLineDateFormat , "stats-one-line-date-format" , "" , ci . StatsOneLineDateFormat , "Enable --stats-one-line-date and use custom formatted date: Enclose date string in double quotes (\"), see https://golang.org/pkg/time/#Time.Format" )
2020-11-05 19:33:32 +08:00
flags . BoolVarP ( flagSet , & ci . ErrorOnNoTransfer , "error-on-no-transfer" , "" , ci . ErrorOnNoTransfer , "Sets exit code 9 if no files are transferred, useful in scripts" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . Progress , "progress" , "P" , ci . Progress , "Show progress during transfer" )
flags . BoolVarP ( flagSet , & ci . ProgressTerminalTitle , "progress-terminal-title" , "" , ci . ProgressTerminalTitle , "Show progress on the terminal title (requires -P/--progress)" )
flags . BoolVarP ( flagSet , & ci . Cookie , "use-cookies" , "" , ci . Cookie , "Enable session cookiejar" )
flags . BoolVarP ( flagSet , & ci . UseMmap , "use-mmap" , "" , ci . UseMmap , "Use mmap allocator (see docs)" )
2023-01-11 15:59:51 +08:00
flags . StringArrayVarP ( flagSet , & ci . CaCert , "ca-cert" , "" , ci . CaCert , "CA certificate used to verify servers" )
2020-11-05 19:33:32 +08:00
flags . StringVarP ( flagSet , & ci . ClientCert , "client-cert" , "" , ci . ClientCert , "Client SSL certificate (PEM) for mutual TLS auth" )
flags . StringVarP ( flagSet , & ci . ClientKey , "client-key" , "" , ci . ClientKey , "Client SSL private key (PEM) for mutual TLS auth" )
2021-08-16 17:30:01 +08:00
flags . FVarP ( flagSet , & ci . MultiThreadCutoff , "multi-thread-cutoff" , "" , "Use multi-thread downloads for files above this size" )
flags . IntVarP ( flagSet , & ci . MultiThreadStreams , "multi-thread-streams" , "" , ci . MultiThreadStreams , "Max number of streams to use for multi-thread downloads" )
2023-06-02 20:00:06 +08:00
flags . FVarP ( flagSet , & ci . MultiThreadWriteBufferSize , "multi-thread-write-buffer-size" , "" , "In memory buffer size for writing when in multi-thread mode" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . UseJSONLog , "use-json-log" , "" , ci . UseJSONLog , "Use json log format" )
2020-11-05 19:33:32 +08:00
flags . StringVarP ( flagSet , & ci . OrderBy , "order-by" , "" , ci . OrderBy , "Instructions on how to order the transfers, e.g. 'size,descending'" )
2020-02-10 15:50:08 +08:00
flags . StringArrayVarP ( flagSet , & uploadHeaders , "header-upload" , "" , nil , "Set HTTP header for upload transactions" )
flags . StringArrayVarP ( flagSet , & downloadHeaders , "header-download" , "" , nil , "Set HTTP header for download transactions" )
2020-04-23 22:24:21 +08:00
flags . StringArrayVarP ( flagSet , & headers , "header" , "" , nil , "Set HTTP header for all transactions" )
2022-05-24 22:46:07 +08:00
flags . StringArrayVarP ( flagSet , & metadataSet , "metadata-set" , "" , nil , "Add metadata key=value when uploading" )
2021-08-16 17:30:01 +08:00
flags . BoolVarP ( flagSet , & ci . RefreshTimes , "refresh-times" , "" , ci . RefreshTimes , "Refresh the modtime of remote files" )
flags . BoolVarP ( flagSet , & ci . NoConsole , "no-console" , "" , ci . NoConsole , "Hide console window (supported on Windows only)" )
flags . StringVarP ( flagSet , & dscp , "dscp" , "" , "" , "Set DSCP value to connections, value or name, e.g. CS1, LE, DF, AF21" )
flags . DurationVarP ( flagSet , & ci . FsCacheExpireDuration , "fs-cache-expire-duration" , "" , ci . FsCacheExpireDuration , "Cache remotes for this long (0 to disable caching)" )
flags . DurationVarP ( flagSet , & ci . FsCacheExpireInterval , "fs-cache-expire-interval" , "" , ci . FsCacheExpireInterval , "Interval to check for expired remotes" )
flags . BoolVarP ( flagSet , & ci . DisableHTTP2 , "disable-http2" , "" , ci . DisableHTTP2 , "Disable HTTP/2 in the global transport" )
flags . BoolVarP ( flagSet , & ci . HumanReadable , "human-readable" , "" , ci . HumanReadable , "Print numbers in a human-readable format, sizes with suffix Ki|Mi|Gi|Ti|Pi" )
2021-10-12 19:57:54 +08:00
flags . DurationVarP ( flagSet , & ci . KvLockTime , "kv-lock-time" , "" , ci . KvLockTime , "Maximum time to keep key-value database locked by process" )
2022-05-30 17:14:37 +08:00
flags . BoolVarP ( flagSet , & ci . DisableHTTPKeepAlives , "disable-http-keep-alives" , "" , ci . DisableHTTPKeepAlives , "Disable HTTP keep-alives and use each connection once." )
2022-05-25 19:18:49 +08:00
flags . BoolVarP ( flagSet , & ci . Metadata , "metadata" , "M" , ci . Metadata , "If set, preserve metadata when copying objects" )
2022-07-04 23:26:08 +08:00
flags . BoolVarP ( flagSet , & ci . ServerSideAcrossConfigs , "server-side-across-configs" , "" , ci . ServerSideAcrossConfigs , "Allow server-side operations (e.g. copy) to work across different configs" )
2022-12-06 20:07:06 +08:00
flags . FVarP ( flagSet , & ci . TerminalColorMode , "color" , "" , "When to show colors (and other ANSI codes) AUTO|NEVER|ALWAYS" )
2023-05-03 17:39:42 +08:00
flags . FVarP ( flagSet , & ci . DefaultTime , "default-time" , "" , "Time to show if modtime is unknown for files and directories" )
2023-04-04 23:19:16 +08:00
flags . BoolVarP ( flagSet , & ci . Inplace , "inplace" , "" , ci . Inplace , "Download directly to destination file instead of atomic download to temp/rename" )
2020-02-10 15:50:08 +08:00
}
// ParseHeaders converts the strings passed in via the header flags into HTTPOptions
func ParseHeaders ( headers [ ] string ) [ ] * fs . HTTPOption {
opts := [ ] * fs . HTTPOption { }
for _ , header := range headers {
parts := strings . SplitN ( header , ":" , 2 )
if len ( parts ) == 1 {
log . Fatalf ( "Failed to parse '%s' as an HTTP header. Expecting a string like: 'Content-Encoding: gzip'" , header )
}
option := & fs . HTTPOption {
Key : strings . TrimSpace ( parts [ 0 ] ) ,
Value : strings . TrimSpace ( parts [ 1 ] ) ,
}
opts = append ( opts , option )
}
return opts
2018-01-13 00:30:54 +08:00
}
2019-04-30 20:06:24 +08:00
// SetFlags converts any flags into config which weren't straight forward
2020-11-05 19:33:32 +08:00
func SetFlags ( ci * fs . ConfigInfo ) {
2021-06-23 00:32:26 +08:00
if dumpHeaders {
ci . Dump |= fs . DumpHeaders
fs . Logf ( nil , "--dump-headers is obsolete - please use --dump headers instead" )
}
if dumpBodies {
ci . Dump |= fs . DumpBodies
fs . Logf ( nil , "--dump-bodies is obsolete - please use --dump bodies instead" )
}
if ci . Dump != 0 && verbose < 2 && ci . LogLevel != fs . LogLevelDebug {
fs . Logf ( nil , "Automatically setting -vv as --dump is enabled" )
verbose = 2
}
2018-01-13 00:30:54 +08:00
if verbose >= 2 {
2020-11-05 19:33:32 +08:00
ci . LogLevel = fs . LogLevelDebug
2018-01-13 00:30:54 +08:00
} else if verbose >= 1 {
2020-11-05 19:33:32 +08:00
ci . LogLevel = fs . LogLevelInfo
2018-01-13 00:30:54 +08:00
}
2020-12-30 03:40:05 +08:00
if ( ci . DryRun || ci . Interactive ) && ci . StatsLogLevel > fs . LogLevelNotice {
ci . StatsLogLevel = fs . LogLevelNotice
}
2018-01-13 00:30:54 +08:00
if quiet {
if verbose > 0 {
log . Fatalf ( "Can't set -v and -q" )
}
2020-11-05 19:33:32 +08:00
ci . LogLevel = fs . LogLevelError
2018-01-13 00:30:54 +08:00
}
logLevelFlag := pflag . Lookup ( "log-level" )
if logLevelFlag != nil && logLevelFlag . Changed {
if verbose > 0 {
log . Fatalf ( "Can't set -v and --log-level" )
}
if quiet {
log . Fatalf ( "Can't set -q and --log-level" )
}
}
2020-11-05 19:33:32 +08:00
if ci . UseJSONLog {
2019-07-26 08:54:09 +08:00
logrus . AddHook ( fsLog . NewCallerHook ( ) )
logrus . SetFormatter ( & logrus . JSONFormatter {
TimestampFormat : "2006-01-02T15:04:05.999999-07:00" ,
} )
logrus . SetLevel ( logrus . DebugLevel )
2020-11-05 19:33:32 +08:00
switch ci . LogLevel {
2019-07-26 08:54:09 +08:00
case fs . LogLevelEmergency , fs . LogLevelAlert :
logrus . SetLevel ( logrus . PanicLevel )
case fs . LogLevelCritical :
logrus . SetLevel ( logrus . FatalLevel )
case fs . LogLevelError :
logrus . SetLevel ( logrus . ErrorLevel )
case fs . LogLevelWarning , fs . LogLevelNotice :
logrus . SetLevel ( logrus . WarnLevel )
case fs . LogLevelInfo :
logrus . SetLevel ( logrus . InfoLevel )
case fs . LogLevelDebug :
logrus . SetLevel ( logrus . DebugLevel )
}
}
2018-01-13 00:30:54 +08:00
switch {
case deleteBefore && ( deleteDuring || deleteAfter ) ,
deleteDuring && deleteAfter :
log . Fatalf ( ` Only one of --delete-before, --delete-during or --delete-after can be used. ` )
case deleteBefore :
2020-11-05 19:33:32 +08:00
ci . DeleteMode = fs . DeleteModeBefore
2018-01-13 00:30:54 +08:00
case deleteDuring :
2020-11-05 19:33:32 +08:00
ci . DeleteMode = fs . DeleteModeDuring
2018-01-13 00:30:54 +08:00
case deleteAfter :
2020-11-05 19:33:32 +08:00
ci . DeleteMode = fs . DeleteModeAfter
2018-01-13 00:30:54 +08:00
default :
2020-11-05 19:33:32 +08:00
ci . DeleteMode = fs . DeleteModeDefault
2018-01-13 00:30:54 +08:00
}
2020-11-16 11:04:29 +08:00
if len ( ci . CompareDest ) > 0 && len ( ci . CopyDest ) > 0 {
2019-07-08 09:02:53 +08:00
log . Fatalf ( ` Can't use --compare-dest with --copy-dest. ` )
}
2019-03-26 10:41:45 +08:00
switch {
2020-11-05 19:33:32 +08:00
case len ( ci . StatsOneLineDateFormat ) > 0 :
ci . StatsOneLineDate = true
ci . StatsOneLine = true
case ci . StatsOneLineDate :
ci . StatsOneLineDateFormat = "2006/01/02 15:04:05 - "
ci . StatsOneLine = true
2019-03-26 10:41:45 +08:00
}
2018-01-13 00:30:54 +08:00
if bindAddr != "" {
addrs , err := net . LookupIP ( bindAddr )
if err != nil {
log . Fatalf ( "--bind: Failed to parse %q as IP address: %v" , bindAddr , err )
}
if len ( addrs ) != 1 {
log . Fatalf ( "--bind: Expecting 1 IP address for %q but got %d" , bindAddr , len ( addrs ) )
}
2020-11-05 19:33:32 +08:00
ci . BindAddr = addrs [ 0 ]
2018-01-13 00:30:54 +08:00
}
if disableFeatures != "" {
if disableFeatures == "help" {
log . Fatalf ( "Possible backend features are: %s\n" , strings . Join ( new ( fs . Features ) . List ( ) , ", " ) )
}
2020-11-05 19:33:32 +08:00
ci . DisableFeatures = strings . Split ( disableFeatures , "," )
2018-01-13 00:30:54 +08:00
}
2020-02-10 15:50:08 +08:00
if len ( uploadHeaders ) != 0 {
2020-11-05 19:33:32 +08:00
ci . UploadHeaders = ParseHeaders ( uploadHeaders )
2020-02-10 15:50:08 +08:00
}
if len ( downloadHeaders ) != 0 {
2020-11-05 19:33:32 +08:00
ci . DownloadHeaders = ParseHeaders ( downloadHeaders )
2020-02-10 15:50:08 +08:00
}
2020-04-23 22:24:21 +08:00
if len ( headers ) != 0 {
2020-11-05 19:33:32 +08:00
ci . Headers = ParseHeaders ( headers )
2020-04-23 22:24:21 +08:00
}
2022-05-24 22:46:07 +08:00
if len ( headers ) != 0 {
ci . Headers = ParseHeaders ( headers )
}
if len ( metadataSet ) != 0 {
ci . MetadataSet = make ( fs . Metadata , len ( metadataSet ) )
for _ , kv := range metadataSet {
equal := strings . IndexRune ( kv , '=' )
if equal < 0 {
log . Fatalf ( "Failed to parse '%s' as metadata key=value." , kv )
}
ci . MetadataSet [ strings . ToLower ( kv [ : equal ] ) ] = kv [ equal + 1 : ]
}
fs . Debugf ( nil , "MetadataUpload %v" , ci . MetadataSet )
}
2021-01-29 11:41:50 +08:00
if len ( dscp ) != 0 {
if value , ok := parseDSCP ( dscp ) ; ok {
ci . TrafficClass = value << 2
} else {
log . Fatalf ( "--dscp: Invalid DSCP name: %v" , dscp )
}
}
2020-02-10 15:50:08 +08:00
2021-04-08 23:49:47 +08:00
// Set path to configuration file
if err := config . SetConfigPath ( configPath ) ; err != nil {
log . Fatalf ( "--config: Failed to set %q as config path: %v" , configPath , err )
2018-01-13 00:30:54 +08:00
}
2019-08-13 05:09:40 +08:00
2021-09-10 21:35:53 +08:00
// Set path to cache dir
if err := config . SetCacheDir ( cacheDir ) ; err != nil {
log . Fatalf ( "--cache-dir: Failed to set %q as cache dir: %v" , cacheDir , err )
}
2021-09-10 20:44:13 +08:00
// Set path to temp dir
if err := config . SetTempDir ( tempDir ) ; err != nil {
log . Fatalf ( "--temp-dir: Failed to set %q as temp dir: %v" , tempDir , err )
}
2019-08-13 05:09:40 +08:00
// Set whether multi-thread-streams was set
multiThreadStreamsFlag := pflag . Lookup ( "multi-thread-streams" )
2020-11-05 19:33:32 +08:00
ci . MultiThreadSet = multiThreadStreamsFlag != nil && multiThreadStreamsFlag . Changed
2019-08-13 05:09:40 +08:00
2021-02-17 01:54:13 +08:00
// Make sure some values are > 0
nonZero := func ( pi * int ) {
if * pi <= 0 {
* pi = 1
}
}
nonZero ( & ci . LowLevelRetries )
nonZero ( & ci . Transfers )
nonZero ( & ci . Checkers )
2018-01-13 00:30:54 +08:00
}
2021-01-29 11:41:50 +08:00
// parseHeaders converts DSCP names to value
func parseDSCP ( dscp string ) ( uint8 , bool ) {
if s , err := strconv . ParseUint ( dscp , 10 , 6 ) ; err == nil {
return uint8 ( s ) , true
}
dscp = strings . ToUpper ( dscp )
switch dscp {
case "BE" :
fallthrough
case "DF" :
fallthrough
case "CS0" :
return 0x00 , true
case "CS1" :
return 0x08 , true
case "AF11" :
return 0x0A , true
case "AF12" :
return 0x0C , true
case "AF13" :
return 0x0E , true
case "CS2" :
return 0x10 , true
case "AF21" :
return 0x12 , true
case "AF22" :
return 0x14 , true
case "AF23" :
return 0x16 , true
case "CS3" :
return 0x18 , true
case "AF31" :
return 0x1A , true
case "AF32" :
return 0x1C , true
case "AF33" :
return 0x1E , true
case "CS4" :
return 0x20 , true
case "AF41" :
return 0x22 , true
case "AF42" :
return 0x24 , true
case "AF43" :
return 0x26 , true
case "CS5" :
return 0x28 , true
case "EF" :
return 0x2E , true
case "CS6" :
return 0x30 , true
case "LE" :
return 0x01 , true
default :
return 0 , false
}
}