+ if (fd >= 0)
+ close(fd);
+
+ // If we hit a directory, now that we've written the directory itself,
+ // recursively scan the directory.
+ if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
+ DIR *dir = opendir(true_path.c_str());
+
+ if (dir == NULL) {
+ fprintf(stderr, "Error: %m\n");
+ return;
+ }
+
+ struct dirent *ent;
+ vector<string> contents;
+ while ((ent = readdir(dir)) != NULL) {
+ string filename(ent->d_name);
+ if (filename == "." || filename == "..")
+ continue;
+ contents.push_back(filename);
+ }
+
+ closedir(dir);
+
+ sort(contents.begin(), contents.end());
+
+ for (vector<string>::iterator i = contents.begin();
+ i != contents.end(); ++i) {
+ const string& filename = *i;
+ if (path == ".")
+ scanfile(filename, include);
+ else
+ scanfile(path + "/" + filename, include);
+ }
+ }
+}
+
+/* Include the specified file path in the backups. Append the path to the
+ * includes list, and to ensure that we actually see the path when scanning the
+ * directory tree, add all the parent directories to the search list, which
+ * means we will scan through the directory listing even if the files
+ * themselves are excluded from being backed up. */
+void add_include(const char *path)
+{
+ printf("Add: %s\n", path);
+ /* Was an absolute path specified? If so, we'll need to start scanning
+ * from the root directory. Make sure that the user was consistent in
+ * providing either all relative paths or all absolute paths. */
+ if (path[0] == '/') {
+ if (includes.size() > 0 && relative_paths == true) {
+ fprintf(stderr,
+ "Error: Cannot mix relative and absolute paths!\n");
+ exit(1);
+ }
+
+ relative_paths = false;
+
+ // Skip over leading '/'
+ path++;
+ } else if (relative_paths == false && path[0] != '/') {
+ fprintf(stderr, "Error: Cannot mix relative and absolute paths!\n");
+ exit(1);