boolean isEncryptionEnabled = false;
boolean isMoveEnabled = false;
boolean isBatchMode = false;
String aclString = null;
int reportLevel = REPORT_LEVEL_ALL;
ProviderCredentials providerCredentials = null;
String providerId = "S3";
// Parse arguments.
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith("-")) {
// Argument is an option.
if (arg.equalsIgnoreCase("-h") || arg.equalsIgnoreCase("--help")) {
printHelpAndExit(true);
} else if (arg.equalsIgnoreCase("-n") || arg.equalsIgnoreCase("--noaction")) {
doAction = false;
} else if (arg.equalsIgnoreCase("-q") || arg.equalsIgnoreCase("--quiet")) {
isQuiet = true;
} else if (arg.equalsIgnoreCase("-p") || arg.equalsIgnoreCase("--noprogress")) {
isNoProgress = true;
} else if (arg.equalsIgnoreCase("-f") || arg.equalsIgnoreCase("--force")) {
isForce = true;
} else if (arg.equalsIgnoreCase("-k") || arg.equalsIgnoreCase("--keepfiles")) {
isKeepFiles = true;
} else if (arg.equalsIgnoreCase("-d") || arg.equalsIgnoreCase("--nodelete")) {
isNoDelete = true;
} else if (arg.equalsIgnoreCase("-g") || arg.equalsIgnoreCase("--gzip")) {
isGzipEnabled = true;
} else if (arg.equalsIgnoreCase("-c") || arg.equalsIgnoreCase("--crypto")) {
isEncryptionEnabled = true;
} else if (arg.equalsIgnoreCase("-m") || arg.equalsIgnoreCase("--move")) {
isMoveEnabled = true;
} else if (arg.equalsIgnoreCase("-s") || arg.equalsIgnoreCase("--skipmetadata")) {
System.err.println("WARNING: --skipmetadata is obsolete since JetS3t 0.8.1, it has no effect");
} else if (arg.equalsIgnoreCase("-b") || arg.equalsIgnoreCase("--batch")) {
isBatchMode = true;
} else if (arg.equalsIgnoreCase("--provider")) {
if (i + 1 < args.length) {
// Read custom Synchronize properties file from the specified file
i++;
providerId = args[i];
if (!"S3".equalsIgnoreCase(providerId)
&& !"GS".equalsIgnoreCase(providerId))
{
System.err.println("ERROR: --provider option must be one of 'S3' or 'GS'");
printHelpAndExit(false);
}
} else {
System.err.println("ERROR: --provider option must be followed by a provider ID 'S3' or 'GS'");
printHelpAndExit(false);
}
} else if (arg.equalsIgnoreCase("--properties")) {
if (i + 1 < args.length) {
// Read custom Synchronize properties file from the specified file
i++;
propertiesFileName = args[i];
File propertiesFile = new File(propertiesFileName);
if (!propertiesFile.canRead()) {
System.err.println("ERROR: The properties file " + propertiesFileName + " could not be found");
System.exit(2);
}
myProperties.loadAndReplaceProperties(
new FileInputStream(propertiesFileName), propertiesFile.getName());
} else {
System.err.println("ERROR: --properties option must be followed by a file path");
printHelpAndExit(false);
}
} else if (arg.equalsIgnoreCase("--acl")) {
if (i + 1 < args.length) {
// Read the acl setting string
i++;
aclString = args[i];
if (!"PUBLIC_READ".equalsIgnoreCase(aclString)
&& !"PUBLIC_READ_WRITE".equalsIgnoreCase(aclString)
&& !"PRIVATE".equalsIgnoreCase(aclString))
{
System.err.println("ERROR: Acess Control List setting \"acl\" must have one of the values "
+ "PRIVATE, PUBLIC_READ, PUBLIC_READ_WRITE");
printHelpAndExit(false);
}
} else {
System.err.println("ERROR: --acl option must be followed by an ACL string");
printHelpAndExit(false);
}
} else if (arg.equalsIgnoreCase("--reportlevel")) {
if (i + 1 < args.length) {
// Read the report level integer
i++;
try {
reportLevel = Integer.parseInt(args[i]);
if (reportLevel < 0 || reportLevel > 3) {
System.err.println("ERROR: Report Level setting \"reportlevel\" must have one of the values "
+ "0 (no reporting), 1 (actions only), 2 (differences only), 3 (DEFAULT - all reporting)");
printHelpAndExit(false);
}
} catch (NumberFormatException e) {
System.err.println("ERROR: --reportlevel option must be followed by 0, 1, 2 or 3");
printHelpAndExit(false);
}
} else {
System.err.println("ERROR: --reportlevel option must be followed by 0, 1, 2 or 3");
printHelpAndExit(false);
}
} else if (arg.equalsIgnoreCase("--credentials")) {
if (i + 1 < args.length) {
// Read the credentials file location
i++;
File credentialsFile = new File(args[i]);
if (!credentialsFile.canRead()) {
System.err.println("ERROR: Cannot read credentials file '" + credentialsFile + "'");
printHelpAndExit(false);
}
while (providerCredentials == null) {
String credentialsPassword = PasswordInput.getPassword(
"Password for credentials file '" + credentialsFile + "'");
try {
providerCredentials = ProviderCredentials.load(credentialsPassword, credentialsFile);
// Set dummy accesskey and secretkey property values, to avoid prompting for these values later on.
myProperties.setProperty("accesskey", "");
myProperties.setProperty("secretkey", "");
} catch (ServiceException e) {
System.out.println("Failed to read credentials from the file '" + credentialsFile + "'");
}
}
} else {
System.err.println("ERROR: --credentials option must be followed by a file path");
printHelpAndExit(false);
}
} else {
System.err.println("ERROR: Invalid option: " + arg);
printHelpAndExit(false);
}
} else {
// Argument is one of the required parameters.
if (reqArgCount == 0) {
actionCommand = arg.toUpperCase(Locale.getDefault());
if (!"UP".equals(actionCommand) && !"DOWN".equals(actionCommand)) {
System.err.println("ERROR: Invalid action command " + actionCommand
+ ". Valid values are 'UP' or 'DOWN'");
printHelpAndExit(false);
}
} else if (reqArgCount == 1) {
servicePath = arg;
} else if (reqArgCount > 1) {
File file = new File(arg);
if ("DOWN".equals(actionCommand)) {
if (reqArgCount > 2) {
System.err.println("ERROR: Only one target directory may be specified"
+ " for " + actionCommand);
printHelpAndExit(false);
}
if (!file.exists()) {
// Create missing target directory
if (!file.mkdirs()) {
System.err.println(
"ERROR: Target download directory does not exist and could not be created: " + file);
System.exit(1);
}
}
if (file.exists() && !file.isDirectory()) {
System.err.println(
"ERROR: Target download location already exists but is not a directory: " + file);
System.exit(1);
}
if (!file.canWrite() || !file.canWrite()) {
System.err.println(
"ERROR: Invalid permissions on target download location, cannot "
+ (!file.canRead()
? "read from" + (!file.canWrite()? " or " : "")
: "")
+ (!file.canWrite() ? "write to" : "")
+ " directory: " + file.getAbsolutePath());
System.exit(1);
}
if (!file.canWrite()) {
System.err.println(
"ERROR: Cannot write to target download location: " + file);
System.exit(1);
}
} else {
if (!file.canRead()) {
if (myProperties != null && myProperties.getBoolProperty("upload.ignoreMissingPaths", false)) {
System.err.println("WARN: Ignoring missing upload path: " + file);
continue;
} else {
System.err.println(
"ERROR: Cannot read upload file/directory: " + file + "\n" +
" To ignore missing paths set the property upload.ignoreMissingPaths");
printHelpAndExit(false);
}
}
}
fileSet.add(file);
}
reqArgCount++;
}
}
if (fileSet.size() < 1
&& !myProperties.getBoolProperty("upload.ignoreMissingPaths", false))
{
// Missing one or more required parameters.
System.err.println("ERROR: Missing required file path(s)");
printHelpAndExit(false);
}
if (isKeepFiles && isNoDelete) {
// Incompatible options.
System.err.println("ERROR: Options --keepfiles and --nodelete cannot be used at the same time");
printHelpAndExit(false);
}
if (isKeepFiles && isMoveEnabled) {
// Incompatible options.
System.err.println("ERROR: Options --keepfiles and --move cannot be used at the same time");
printHelpAndExit(false);
}
// Ensure the Synchronize properties file contains everything we need, and prompt
// for any required information that is missing.
if (!myProperties.containsKey("accesskey")
|| !myProperties.containsKey("secretkey")
|| (isEncryptionEnabled && !myProperties.containsKey("password")))
{
System.out.println("Please enter the required properties that have not been provided in a properties file:");
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
if (!myProperties.containsKey("accesskey")) {
System.out.print("Acccess Key: ");
myProperties.setProperty("accesskey", inputReader.readLine());
}
if (!myProperties.containsKey("secretkey")) {
System.out.print("Secret Key: ");
myProperties.setProperty("secretkey", inputReader.readLine());
}
if (isEncryptionEnabled && !myProperties.containsKey("password")) {
String password1 = "password1";
String password2 = "password2";
while (!password1.equals(password2)) {
password1 = PasswordInput.getPassword("Encryption password");
password2 = PasswordInput.getPassword("Confirm password");
if (!password1.equals(password2)) {
System.out.println("The original and confirmation passwords do not match, try again.");
}
}
myProperties.setProperty("password", password1);
}
}
// Use property values for the credentials, if we haven't already been
// given the credentials through the --credentials argument.
if (providerCredentials == null) {
if ("S3".equalsIgnoreCase(providerId)) {
providerCredentials = new AWSCredentials(
myProperties.getStringProperty("accesskey", null),
myProperties.getStringProperty("secretkey", null));
} else if ("GS".equalsIgnoreCase(providerId)) {
providerCredentials = new GSCredentials(
myProperties.getStringProperty("accesskey", null),
myProperties.getStringProperty("secretkey", null));
}
}
// Sanity-check credentials -- if both are null or empty strings,
// then nullify the credentials object to get an anonymous connection.
if (providerCredentials.getAccessKey() == null || providerCredentials.getAccessKey().length() == 0
|| providerCredentials.getSecretKey() == null || providerCredentials.getSecretKey().length() == 0)
{
providerCredentials = null;
}
if (aclString == null) {