diff options
Diffstat (limited to 'bin/bbackupctl/bbackupctl.cpp')
-rw-r--r-- | bin/bbackupctl/bbackupctl.cpp | 202 |
1 files changed, 154 insertions, 48 deletions
diff --git a/bin/bbackupctl/bbackupctl.cpp b/bin/bbackupctl/bbackupctl.cpp index dfadc37d..6f7c55f7 100644 --- a/bin/bbackupctl/bbackupctl.cpp +++ b/bin/bbackupctl/bbackupctl.cpp @@ -28,16 +28,26 @@ #include "MemLeakFindOn.h" +enum Command +{ + Default, + WaitForSyncStart, + WaitForSyncEnd, + SyncAndWaitForEnd, +}; + void PrintUsageAndExit() { printf("Usage: bbackupctl [-q] [-c config_file] <command>\n" "Commands are:\n" - " sync -- start a syncronisation run now\n" - " force-sync -- force the start of a syncronisation run, " + " sync -- start a synchronisation (backup) run now\n" + " force-sync -- force the start of a synchronisation run, " "even if SyncAllowScript says no\n" " reload -- reload daemon configuration\n" " terminate -- terminate daemon now\n" " wait-for-sync -- wait until the next sync starts, then exit\n" + " wait-for-end -- wait until the next sync finishes, then exit\n" + " sync-and-wait -- start sync, wait until it finishes, then exit\n" ); exit(1); } @@ -107,7 +117,10 @@ int main(int argc, const char *argv[]) // Check there's a socket defined in the config file if(!conf.KeyExists("CommandSocket")) { - printf("Daemon isn't using a control socket, could not execute command.\nAdd a CommandSocket declaration to the bbackupd.conf file.\n"); + printf("Daemon isn't using a control socket, " + "could not execute command.\n" + "Add a CommandSocket declaration to the " + "bbackupd.conf file.\n"); return 1; } @@ -188,68 +201,161 @@ int main(int argc, const char *argv[]) // Print summary? if(!quiet) { - printf("Daemon configuration summary:\n" \ - " AutomaticBackup = %s\n" \ - " UpdateStoreInterval = %d seconds\n" \ - " MinimumFileAge = %d seconds\n" \ - " MaxUploadWait = %d seconds\n", - autoBackup?"true":"false", updateStoreInterval, minimumFileAge, maxUploadWait); + printf("Daemon configuration summary:\n" + " AutomaticBackup = %s\n" + " UpdateStoreInterval = %d seconds\n" + " MinimumFileAge = %d seconds\n" + " MaxUploadWait = %d seconds\n", + autoBackup?"true":"false", updateStoreInterval, + minimumFileAge, maxUploadWait); } - // Is the command the "wait for sync to start" command? - bool areWaitingForSync = false; - if(::strcmp(argv[0], "wait-for-sync") == 0) + std::string stateLine; + if(!getLine.GetLine(stateLine) || getLine.IsEOF()) { - // Check that it's not in non-automatic mode, because then it'll never start - if(!autoBackup) - { - printf("ERROR: Daemon is not in automatic mode -- sync will never start!\n"); - return 1; - } - - // Yes... set the flag so we know what we're waiting for a sync to start - areWaitingForSync = true; +#if defined WIN32 && ! defined NDEBUG + syslog(LOG_ERR, "Failed to receive state line from daemon"); +#else + printf("Failed to receive state line from daemon\n"); +#endif + return 1; + } + + // Decode it + int currentState; + if(::sscanf(stateLine.c_str(), "state %d", ¤tState) != 1) + { + printf("State line didn't decode\n"); + return 1; } - else + + Command command = Default; + std::string commandName(argv[0]); + + if (commandName == "wait-for-sync") + { + command = WaitForSyncStart; + } + else if (commandName == "wait-for-end") { - // No? Just send the command given plus a quit command. - std::string cmd(argv[0]); - cmd += "\nquit\n"; - connection.Write(cmd.c_str(), cmd.size()); + command = WaitForSyncEnd; + } + else if (commandName == "sync-and-wait") + { + command = SyncAndWaitForEnd; + } + + switch (command) + { + case WaitForSyncStart: + case WaitForSyncEnd: + { + // Check that it's not in non-automatic mode, + // because then it'll never start + + if(!autoBackup) + { + printf("ERROR: Daemon is not in automatic mode -- " + "sync will never start!\n"); + return 1; + } + + } + break; + + case SyncAndWaitForEnd: + { + // send a sync command + std::string cmd("force-sync\n"); + connection.Write(cmd.c_str(), cmd.size()); + connection.WriteAllBuffered(); + + if (currentState != 0) + { + printf("Waiting for current sync/error state " + "to finish...\n"); + } + } + break; + + default: + { + // Normal case, just send the command given + // plus a quit command. + std::string cmd = commandName; + cmd += "\nquit\n"; + connection.Write(cmd.c_str(), cmd.size()); + } } // Read the response std::string line; - while(!getLine.IsEOF() && getLine.GetLine(line)) + bool syncIsRunning = false; + bool finished = false; + + while(!finished && !getLine.IsEOF() && getLine.GetLine(line)) { - if(areWaitingForSync) + switch (command) { - // Need to wait for the state change... - if(line == "start-sync") + case WaitForSyncStart: { - // Send a quit command to finish nicely - connection.Write("quit\n", 5); - - // And we're done - break; - } - } - else - { - // Is this an OK or error line? - if(line == "ok") + // Need to wait for the state change... + if(line == "start-sync") + { + // Send a quit command to finish nicely + connection.Write("quit\n", 5); + + // And we're done + finished = true; + } + } + break; + + case WaitForSyncEnd: + case SyncAndWaitForEnd: { - if(!quiet) + if(line == "start-sync") + { + if (!quiet) printf("Sync started...\n"); + syncIsRunning = true; + } + else if(line == "finish-sync") { - printf("Succeeded.\n"); + if (syncIsRunning) + { + if (!quiet) printf("Sync finished.\n"); + // Send a quit command to finish nicely + connection.Write("quit\n", 5); + + // And we're done + finished = true; + } + else + { + if (!quiet) printf("Previous sync finished.\n"); + } + // daemon must still be busy } - break; } - else if(line == "error") + break; + + default: { - printf("ERROR. (Check command spelling)\n"); - returnCode = 1; - break; + // Is this an OK or error line? + if(line == "ok") + { + if(!quiet) + { + printf("Succeeded.\n"); + } + finished = true; + } + else if(line == "error") + { + printf("ERROR. (Check command spelling)\n"); + returnCode = 1; + finished = true; + } } } } |