+/* Read the next entry from the old statcache file, loading it into
+ * old_metadata. */
+void MetadataWriter::read_statcache()
+{
+ if (statcache_in == NULL) {
+ old_metadata_eof = true;
+ return;
+ }
+
+ old_metadata.clear();
+
+ char *buf = NULL;
+ size_t n = 0;
+ string field = ""; // Last field to be read in
+
+ /* Look for a first line starting with "@@", which tells where the metadata
+ * can be found in the metadata log of an old snapshot. */
+ if (getline(&buf, &n, statcache_in) < 0
+ || buf == NULL || buf[0] != '@' || buf[1] != '@') {
+ old_metadata_eof = true;
+ return;
+ }
+
+ if (strchr(buf, '\n') != NULL)
+ *strchr(buf, '\n') = '\0';
+ old_metadata_loc = buf + 2;
+
+ /* After the initial line follows the metadata, as key-value pairs. */
+ while (!feof(statcache_in)) {
+ if (getline(&buf, &n, statcache_in) < 0)
+ break;
+
+ char *eol = strchr(buf, '\n');
+ if (eol != NULL)
+ *eol = '\0';
+
+ /* Is the line blank? If so, we have reached the end of this entry. */
+ if (buf[0] == '\0')
+ break;
+
+ /* Is this a continuation line? (Does it start with whitespace?) */
+ if (isspace(buf[0]) && field != "") {
+ old_metadata[field] += string("\n") + buf;
+ continue;
+ }
+
+ /* For lines of the form "Key: Value" look for ':' and split the line
+ * apart. */
+ char *value = strchr(buf, ':');
+ if (value == NULL)
+ continue;
+ *value = '\0';
+ field = buf;
+
+ value++;
+ while (isspace(*value))
+ value++;
+
+ old_metadata[field] = value;
+ }
+
+ if (feof(statcache_in) && old_metadata.size() == 0) {
+ old_metadata_eof = true;
+ }
+
+ free(buf);
+}
+
+bool MetadataWriter::find(const string& path)
+{
+ const char *path_str = path.c_str();
+ while (!old_metadata_eof) {
+ string old_path = uri_decode(old_metadata["path"]);
+ int cmp = pathcmp(old_path.c_str(), path_str);
+ if (cmp == 0)
+ return true;
+ else if (cmp > 0)
+ return false;
+ else
+ read_statcache();
+ }
+
+ return false;
+}
+