1 #include "filesys/fsutil.h"
7 #include "filesys/directory.h"
8 #include "filesys/file.h"
9 #include "filesys/filesys.h"
10 #include "devices/disk.h"
11 #include "threads/malloc.h"
12 #include "threads/palloc.h"
13 #include "threads/vaddr.h"
15 /* List files in the root directory. */
17 fsutil_ls (char **argv UNUSED)
20 char name[NAME_MAX + 1];
22 printf ("Files in the root directory:\n");
23 dir = dir_open_root ();
25 PANIC ("root dir open failed");
26 while (dir_readdir (dir, name))
27 printf ("%s\n", name);
28 printf ("End of listing.\n");
31 /* Prints the contents of file ARGV[1] to the system console as
34 fsutil_cat (char **argv)
36 const char *file_name = argv[1];
41 printf ("Printing '%s' to the console...\n", file_name);
42 file = filesys_open (file_name);
44 PANIC ("%s: open failed", file_name);
45 buffer = palloc_get_page (PAL_ASSERT);
48 off_t pos = file_tell (file);
49 off_t n = file_read (file, buffer, PGSIZE);
53 hex_dump (pos, buffer, n, true);
55 palloc_free_page (buffer);
59 /* Deletes file ARGV[1]. */
61 fsutil_rm (char **argv)
63 const char *file_name = argv[1];
65 printf ("Deleting '%s'...\n", file_name);
66 if (!filesys_remove (file_name))
67 PANIC ("%s: delete failed\n", file_name);
70 /* Extracts a ustar-format tar archive from the scratch disk, hdc
71 or hd1:0, into the Pintos file system. */
73 fsutil_extract (char **argv UNUSED)
75 static disk_sector_t sector = 0;
80 /* Allocate buffers. */
81 header = malloc (DISK_SECTOR_SIZE);
82 data = malloc (DISK_SECTOR_SIZE);
83 if (header == NULL || data == NULL)
84 PANIC ("couldn't allocate buffers");
86 /* Open source disk. */
87 src = disk_get (1, 0);
89 PANIC ("couldn't open scratch disk (hdc or hd1:0)");
91 printf ("Extracting ustar archive from scratch disk into file system...\n");
95 const char *file_name;
100 /* Read and parse ustar header. */
101 disk_read (src, sector++, header);
102 error = ustar_parse_header (header, &file_name, &type, &size);
104 PANIC ("bad ustar header in sector %"PRDSNu" (%s)", sector - 1, error);
106 if (type == USTAR_EOF)
108 /* End of archive. */
111 else if (type == USTAR_DIRECTORY)
112 printf ("ignoring directory %s\n", file_name);
113 else if (type == USTAR_REGULAR)
117 printf ("Putting '%s' into the file system...\n", file_name);
119 /* Create destination file. */
120 if (!filesys_create (file_name, size))
121 PANIC ("%s: create failed", file_name);
122 dst = filesys_open (file_name);
124 PANIC ("%s: open failed", file_name);
129 int chunk_size = (size > DISK_SECTOR_SIZE
132 disk_read (src, sector++, data);
133 if (file_write (dst, data, chunk_size) != chunk_size)
134 PANIC ("%s: write failed with %d bytes unwritten",
144 /* Erase the ustar header from the start of the disk, so that
145 the extraction operation is idempotent. We erase two blocks
146 because two blocks of zeros are the ustar end-of-archive
148 printf ("Erasing ustar archive...\n");
149 memset (header, 0, DISK_SECTOR_SIZE);
150 disk_write (src, 0, header);
151 disk_write (src, 1, header);
157 /* Copies file FILE_NAME from the file system to the scratch
158 disk, in ustar format.
160 The first call to this function will write starting at the
161 beginning of the scratch disk. Later calls advance across the
162 disk. This position is independent of that used for
163 fsutil_extract(), so `extract' should precede all
166 fsutil_append (char **argv)
168 static disk_sector_t sector = 0;
170 const char *file_name = argv[1];
176 printf ("Appending '%s' to ustar archive on scratch disk...\n", file_name);
178 /* Allocate buffer. */
179 buffer = malloc (DISK_SECTOR_SIZE);
181 PANIC ("couldn't allocate buffer");
183 /* Open source file. */
184 src = filesys_open (file_name);
186 PANIC ("%s: open failed", file_name);
187 size = file_length (src);
189 /* Open target disk. */
190 dst = disk_get (1, 0);
192 PANIC ("couldn't open target disk (hdc or hd1:0)");
194 /* Write ustar header to first sector. */
195 if (!ustar_make_header (file_name, USTAR_REGULAR, size, buffer))
196 PANIC ("%s: name too long for ustar format", file_name);
197 disk_write (dst, sector++, buffer);
202 int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
203 if (sector >= disk_size (dst))
204 PANIC ("%s: out of space on scratch disk", file_name);
205 if (file_read (src, buffer, chunk_size) != chunk_size)
206 PANIC ("%s: read failed with %"PROTd" bytes unread", file_name, size);
207 memset (buffer + chunk_size, 0, DISK_SECTOR_SIZE - chunk_size);
208 disk_write (dst, sector++, buffer);
212 /* Write ustar end-of-archive marker, which is two consecutive
213 sectors full of zeros. Don't advance our position past
214 them, though, in case we have more files to append. */
215 memset (buffer, 0, DISK_SECTOR_SIZE);
216 disk_write (dst, sector, buffer);
217 disk_write (dst, sector, buffer + 1);