]> wimlib.net Git - wimlib/blobdiff - src/lookup_table.c
Only access struct stat.mtim if available
[wimlib] / src / lookup_table.c
index cc71c8bec4e19b6adc6a59e0a04bb6fb9d8e67a4..364f469ed08ab7a89426d72f6d41df8868385023 100644 (file)
@@ -122,6 +122,8 @@ clone_lookup_table_entry(const struct lookup_table_entry *old)
                }
                break;
 #endif
+       default:
+               break;
        }
        return new;
 out_free:
@@ -154,7 +156,6 @@ void free_lookup_table_entry(struct lookup_table_entry *lte)
                default:
                        break;
                }
-               FREE(lte->extracted_file);
                FREE(lte);
        }
 }
@@ -217,8 +218,8 @@ static void finalize_lte(struct lookup_table_entry *lte)
 void lte_decrement_refcnt(struct lookup_table_entry *lte,
                          struct lookup_table *table)
 {
-       wimlib_assert(lte);
-       wimlib_assert(lte->refcnt);
+       wimlib_assert(lte != NULL);
+       wimlib_assert(lte->refcnt != 0);
        if (--lte->refcnt == 0) {
                lookup_table_unlink(table, lte);
        #ifdef WITH_FUSE
@@ -231,10 +232,11 @@ void lte_decrement_refcnt(struct lookup_table_entry *lte,
 #ifdef WITH_FUSE
 void lte_decrement_num_opened_fds(struct lookup_table_entry *lte)
 {
-       wimlib_assert(lte);
-       wimlib_assert(lte->num_opened_fds);
-       if (--lte->num_opened_fds == 0 && lte->refcnt == 0)
-               finalize_lte(lte);
+       wimlib_assert(lte != NULL);
+       if (lte->num_opened_fds != 0) {
+               if (--lte->num_opened_fds == 0 && lte->refcnt == 0)
+                       finalize_lte(lte);
+       }
 }
 #endif
 
@@ -363,6 +365,14 @@ int read_lookup_table(WIMStruct *w)
                        ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
                        goto out_free_cur_entry;
                }
+               if ((cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)
+                   && cur_entry->refcnt != 1)
+               {
+                       ERROR("Found metadata resource with refcnt != 1:");
+                       print_lookup_table_entry(cur_entry);
+                       ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
+                       goto out_free_cur_entry;
+               }
                lookup_table_insert(table, cur_entry);
 
        }
@@ -408,6 +418,33 @@ int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out)
        return 0;
 }
 
+/* Writes the lookup table to the output file. */
+int write_lookup_table(struct lookup_table *table, FILE *out,
+                      struct resource_entry *out_res_entry)
+{
+       off_t start_offset, end_offset;
+       int ret;
+
+       start_offset = ftello(out);
+       if (start_offset == -1)
+               return WIMLIB_ERR_WRITE;
+
+       ret = for_lookup_table_entry(table, write_lookup_table_entry, out);
+       if (ret != 0)
+               return ret;
+
+       end_offset = ftello(out);
+       if (end_offset == -1)
+               return WIMLIB_ERR_WRITE;
+
+       out_res_entry->offset        = start_offset;
+       out_res_entry->size          = end_offset - start_offset;
+       out_res_entry->original_size = end_offset - start_offset;
+       out_res_entry->flags         = WIM_RESHDR_FLAG_METADATA;
+
+       return 0;
+}
+
 
 int lte_zero_real_refcnt(struct lookup_table_entry *lte, void *ignore)
 {
@@ -421,13 +458,21 @@ int lte_zero_out_refcnt(struct lookup_table_entry *lte, void *ignore)
        return 0;
 }
 
-int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignone)
+int lte_zero_extracted_file(struct lookup_table_entry *lte, void *ignore)
 {
-       FREE(lte->extracted_file);
        lte->extracted_file = NULL;
        return 0;
 }
 
+int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignore)
+{
+       if (lte->extracted_file != NULL) {
+               FREE(lte->extracted_file);
+               lte->extracted_file = NULL;
+       }
+       return 0;
+}
+
 void print_lookup_table_entry(const struct lookup_table_entry *lte)
 {
        if (!lte) {
@@ -581,7 +626,7 @@ out:
 }
 #endif
 
-static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
+void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
 {
        struct lookup_table_entry *lte;
 
@@ -659,7 +704,7 @@ int dentry_unresolve_ltes(struct dentry *dentry, void *ignore)
  */
 struct lookup_table_entry *
 inode_unnamed_lte(const struct inode *inode,
-                  const struct lookup_table *table)
+                 const struct lookup_table *table)
 {
        if (inode->resolved)
                return inode_unnamed_lte_resolved(inode);
@@ -667,3 +712,16 @@ inode_unnamed_lte(const struct inode *inode,
                return inode_unnamed_lte_unresolved(inode, table);
 }
 
+static int lte_add_stream_size(struct lookup_table_entry *lte,
+                              void *total_bytes_p)
+{
+       *(u64*)total_bytes_p += lte->resource_entry.size;
+       return 0;
+}
+
+u64 lookup_table_total_stream_size(struct lookup_table *table)
+{
+       u64 total_size = 0;
+       for_lookup_table_entry(table, lte_add_stream_size, &total_size);
+       return total_size;
+}