As reported earlier, I’m trying to write a C++ program to let me know whether my backup program is working properly or not.
Having gotten the Eclipse-CDT IDE up and running, I started on the code.
My first task was figuring out how to tell the date and time of a backup from the backup directory itself. This isn’t as difficult as it sounds, because Simple Backup uses the extended ISO date/time that the backup was started as the main component of the subdirectory name.
Identifying whether a particular directory name was a valid Simple Backup directory, and extracting the date and time from it, were a fairly simple matter using standard C++ string operations. They were made even simpler using the Boost library’s regular expressions module.
A Simple Backup directory name looks like this:
2007-07-02_14.57.17.558834.ubuntu.ful
The first part is the date (July second, 2007), then the time (2:57:17pm, plus a fraction), followed by the name of the machine (“ubuntu” — not very imaginative, but quite descriptive, since it’s the only machine running it here), followed by either “.ful” or “.inc”, depending on whether this was a full or incremental backup day. That’s a fairly simple regular expression, if you know regular expressions fairly well:
(\d{4}-\d{2}-\d{2})_(\d{2}\.\d{2}\.\d{2}\.\d+)\.(.+).(ful|inc)
What’s more, that regular expression can be used in a single function call to verify that the thing we’re looking at is a valid backup directory name and extract the date, the time, and the computer name too (that’s what the extra parentheses are for). Here’s the code to do so (directoryName is a constant std::string reference):
boost::regex expr("(\\d{4}-\\d{2}-\\d{2})_(\\d{2}\\.\\d{2}\\.\\d{2}\\.\\d+)\\.(.+).(ful|inc)");
boost::smatch m;
bool validName=boost::regex_match(directoryName, m, expr);
If it’s a valid directory name, m[1].str() will return the date part, m[2].str() will return the time part, and m[3].str() will return the computer name. Very elegant. 🙂
Working with dates and times in C/C++ has always been something of a pain. It’s fairly straightforward, but it generally requires a lot of repetitious coding. The Boost library solves that too; here’s the code to turn the date and time parts of the string into a time value:
using namespace boost::posix_time;
using namespace boost::gregorian;
ptime t(time_from_string(m[1].str()+' '+m[2].str()));
Once we’ve got that, we want to see how old it is. That’s a simple matter too:
ptime now=second_clock::local_time();
time_duration age=time_period(t, now).length();
After that, seeing how many hours old it is is simplicity itself:
cout << "Backup is " << age.hours() << " hours old." << endl;
See, C++ doesn’t have to be as awkward and low-level as you thought. 😉
So we now have a way to see how old the most recent backup is, by the filename. We’ll use the ssh program to actually get a list of filenames and pipe them to this program’s standard input, then write the text that we want to display to standard output, so that we can do the rest as a bash script.
I’m releasing this under an MIT open-source license, so you’re free to use it for whatever you wish. The backupage.cpp source code file, the checkbackup.sh shell script, and the makefile are all in the backupage.tgz archive here.
Once you get the backupage.cpp file compiled, just put the ‘backupage’ executable and the ‘checkbackup.sh’ shell script into the /usr/local/bin directory. You may also need to use the command…
sudo ldconfig -v /usr/local/lib/
…to tell your system where to find the Boost library files (that will only be necessary once). Then you can call checkbackup.sh, manually or from cron, any time you wish to know the age of the most recent backup. 🙂
(CORRECTION: you’ll need to run that ldconfig command once per reboot. I’ve set it up to work automatically here, by using visudo to tell the system that it doesn’t need a sudo password for /sbin/ldconfig and then using a startup script. Also, it looks like cron isn’t able to start this, for reasons I haven’t yet figured out; I’ll add another entry after I’ve modified the program to get around that.)