- int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
- disk_read (src, sector++, buffer);
- if (file_write (dst, buffer, chunk_size) != chunk_size)
- PANIC ("%s: write failed with %lld bytes unwritten",
- filename, (unsigned long long) size);
- size -= chunk_size;
+ const char *file_name;
+ const char *error;
+ enum ustar_type type;
+ int size;
+
+ /* Read and parse ustar header. */
+ disk_read (src, sector++, header);
+ error = ustar_parse_header (header, &file_name, &type, &size);
+ if (error != NULL)
+ PANIC ("bad ustar header in sector %"PRDSNu" (%s)", sector - 1, error);
+
+ if (type == USTAR_EOF)
+ {
+ /* End of archive. */
+ break;
+ }
+ else if (type == USTAR_DIRECTORY)
+ printf ("ignoring directory %s\n", file_name);
+ else if (type == USTAR_REGULAR)
+ {
+ struct file *dst;
+
+ printf ("Putting '%s' into the file system...\n", file_name);
+
+ /* Create destination file. */
+ if (!filesys_create (file_name, size))
+ PANIC ("%s: create failed", file_name);
+ dst = filesys_open (file_name);
+ if (dst == NULL)
+ PANIC ("%s: open failed", file_name);
+
+ /* Do copy. */
+ while (size > 0)
+ {
+ int chunk_size = (size > DISK_SECTOR_SIZE
+ ? DISK_SECTOR_SIZE
+ : size);
+ disk_read (src, sector++, data);
+ if (file_write (dst, data, chunk_size) != chunk_size)
+ PANIC ("%s: write failed with %d bytes unwritten",
+ file_name, size);
+ size -= chunk_size;
+ }
+
+ /* Finish up. */
+ file_close (dst);
+ }