sqlite3_finalize(stmt);
}
+
+bool LocalDb::GetSegmentChecksum(const string &segment,
+ string *seg_path,
+ string *seg_checksum)
+{
+ int rc;
+ sqlite3_stmt *stmt;
+ ObjectReference ref;
+ int found = false;
+
+ stmt = Prepare("select path, checksum from segments where segment = ?");
+ sqlite3_bind_text(stmt, 1, segment.c_str(), segment.size(),
+ SQLITE_TRANSIENT);
+
+ rc = sqlite3_step(stmt);
+ if (rc == SQLITE_DONE) {
+ } else if (rc == SQLITE_ROW) {
+ found = true;
+ const char *val;
+
+ val = (const char *)sqlite3_column_text(stmt, 0);
+ if (val == NULL)
+ found = false;
+ else
+ *seg_path = val;
+
+ val = (const char *)sqlite3_column_text(stmt, 1);
+ if (val == NULL)
+ found = false;
+ else
+ *seg_checksum = val;
+ } else {
+ fprintf(stderr, "Could not execute SELECT statement!\n");
+ ReportError(rc);
+ }
+
+ sqlite3_finalize(stmt);
+
+ return found;
+}
tss->dump_stats();
delete tss;
+ /* Write out a checksums file which lists the checksums for all the
+ * segments included in this snapshot. The format is designed so that it
+ * may be easily verified using the sha1sums command. */
+ const char csum_type[] = "sha1";
+ string checksum_filename = backup_dest + "/snapshot-";
+ if (backup_scheme.size() > 0)
+ checksum_filename += backup_scheme + "-";
+ checksum_filename = checksum_filename + desc_buf + "." + csum_type + "sums";
+ FILE *checksums = fopen(checksum_filename.c_str(), "w");
+ if (checksums != NULL) {
+ for (std::set<string>::iterator i = segment_list.begin();
+ i != segment_list.end(); ++i) {
+ string seg_path, seg_csum;
+ if (db->GetSegmentChecksum(*i, &seg_path, &seg_csum)) {
+ const char *raw_checksum = NULL;
+ if (strncmp(seg_csum.c_str(), csum_type,
+ strlen(csum_type)) == 0) {
+ raw_checksum = seg_csum.c_str() + strlen(csum_type);
+ if (*raw_checksum == '=')
+ raw_checksum++;
+ else
+ raw_checksum = NULL;
+ }
+
+ if (raw_checksum != NULL)
+ fprintf(checksums, "%s *%s\n",
+ raw_checksum, seg_path.c_str());
+ }
+ }
+ fclose(checksums);
+ } else {
+ fprintf(stderr, "ERROR: Unable to write checksums file: %m\n");
+ }
+
db->Close();
/* Write a backup descriptor file, which says which segments are needed and
descriptor << "Scheme: " << backup_scheme << "\n";
descriptor << "Root: " << backup_root << "\n";
+ SHA1Checksum checksum_csum;
+ if (checksum_csum.process_file(checksum_filename.c_str())) {
+ descriptor << "Checksum-File: " << checksum_csum.checksum_str() << "\n";
+ }
+
descriptor << "Segments:\n";
for (std::set<string>::iterator i = segment_list.begin();
i != segment_list.end(); ++i) {