+ for (i = 0; i < dev_tbl->size; i++) {
+ if (dev_tbl->buckets[i].data)
+ ihash_destroy(dev_tbl->buckets[i].data);
+ }
+
+ ihash_destroy(dev_tbl);
+}
+
+static int hlink_compare_gnum(int *int1, int *int2)
+{
+ struct file_struct *f1 = FPTR(*int1);
+ struct file_struct *f2 = FPTR(*int2);
+ int32 gnum1 = F_HL_GNUM(f1);
+ int32 gnum2 = F_HL_GNUM(f2);
+
+ if (gnum1 != gnum2)
+ return gnum1 > gnum2 ? 1 : -1;
+
+ return *int1 > *int2 ? 1 : -1;
+}
+
+static void match_gnums(int32 *ndx_list, int ndx_count)
+{
+ int32 from, prev;
+ struct file_struct *file, *file_next;
+ int32 gnum, gnum_next;
+
+ qsort(ndx_list, ndx_count, sizeof ndx_list[0],
+ (int (*)()) hlink_compare_gnum);
+
+ for (from = 0; from < ndx_count; from++) {
+ for (file = FPTR(ndx_list[from]), gnum = F_HL_GNUM(file), prev = -1;
+ from < ndx_count-1;
+ file = file_next, gnum = gnum_next, prev = ndx_list[from++])
+ {
+ file_next = FPTR(ndx_list[from+1]);
+ gnum_next = F_HL_GNUM(file_next);
+ if (gnum != gnum_next)
+ break;
+ if (prev < 0)
+ file->flags |= FLAG_HLINK_FIRST;
+ F_HL_PREV(file) = prev;
+ }
+ if (prev < 0)
+ file->flags &= ~FLAG_HLINKED;
+ else {
+ file->flags |= FLAG_HLINK_LAST;
+ F_HL_PREV(file) = prev;
+ }
+ }
+}
+
+/* Analyze the hard-links in the file-list by creating a list of all the
+ * items that have hlink data, sorting them, and matching up identical
+ * values into clusters. These will be a single linked list from last
+ * to first when we're done. */
+void match_hard_links(void)
+{
+ int i, ndx_count = 0;
+ int32 *ndx_list;