+ printf ("Appending '%s' to ustar archive on scratch device...\n", file_name);
+
+ /* Allocate buffer. */
+ buffer = malloc (BLOCK_SECTOR_SIZE);
+ if (buffer == NULL)
+ PANIC ("couldn't allocate buffer");
+
+ /* Open source file. */
+ src = filesys_open (file_name);
+ if (src == NULL)
+ PANIC ("%s: open failed", file_name);
+ size = file_length (src);
+
+ /* Open target block device. */
+ dst = block_get_role (BLOCK_SCRATCH);
+ if (dst == NULL)
+ PANIC ("couldn't open scratch device");
+
+ /* Write ustar header to first sector. */
+ if (!ustar_make_header (file_name, USTAR_REGULAR, size, buffer))
+ PANIC ("%s: name too long for ustar format", file_name);
+ block_write (dst, sector++, buffer);
+
+ /* Do copy. */
+ while (size > 0)
+ {
+ int chunk_size = size > BLOCK_SECTOR_SIZE ? BLOCK_SECTOR_SIZE : size;
+ if (sector >= block_size (dst))
+ PANIC ("%s: out of space on scratch device", file_name);
+ if (file_read (src, buffer, chunk_size) != chunk_size)
+ PANIC ("%s: read failed with %"PROTd" bytes unread", file_name, size);
+ memset (buffer + chunk_size, 0, BLOCK_SECTOR_SIZE - chunk_size);
+ block_write (dst, sector++, buffer);
+ size -= chunk_size;