00001 #include "filesys/fsutil.h"
00002
00003 #include <debug.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <ustar.h>
00008 #include "filesys/directory.h"
00009 #include "filesys/file.h"
00010 #include "filesys/filesys.h"
00011 #include "threads/malloc.h"
00012 #include "threads/palloc.h"
00013 #include "threads/vaddr.h"
00014
00015
00016 void
00017 fsutil_ls (char **argv UNUSED)
00018 {
00019 struct dir *dir;
00020 char name[NAME_MAX + 1];
00021
00022 printf ("Files in the root directory:\n");
00023 dir = dir_open_root ();
00024 if (dir == NULL)
00025 PANIC ("root dir open failed");
00026 while (dir_readdir (dir, name))
00027 printf ("%s\n", name);
00028 printf ("End of listing.\n");
00029 }
00030
00031
00032
00033 void
00034 fsutil_cat (char **argv)
00035 {
00036 const char *file_name = argv[1];
00037
00038 struct file *file;
00039 char *buffer;
00040
00041 printf ("Printing '%s' to the console...\n", file_name);
00042 file = filesys_open (file_name);
00043 if (file == NULL)
00044 PANIC ("%s: open failed", file_name);
00045 buffer = palloc_get_page (PAL_ASSERT);
00046 for (;;)
00047 {
00048 off_t pos = file_tell (file);
00049 off_t n = file_read (file, buffer, PGSIZE);
00050 if (n == 0)
00051 break;
00052
00053 hex_dump (pos, buffer, n, true);
00054 }
00055 palloc_free_page (buffer);
00056 file_close (file);
00057 }
00058
00059
00060 void
00061 fsutil_rm (char **argv)
00062 {
00063 const char *file_name = argv[1];
00064
00065 printf ("Deleting '%s'...\n", file_name);
00066 if (!filesys_remove (file_name))
00067 PANIC ("%s: delete failed\n", file_name);
00068 }
00069
00070
00071
00072 void
00073 fsutil_extract (char **argv UNUSED)
00074 {
00075 static block_sector_t sector = 0;
00076
00077 struct block *src;
00078 void *header, *data;
00079
00080
00081 header = malloc (BLOCK_SECTOR_SIZE);
00082 data = malloc (BLOCK_SECTOR_SIZE);
00083 if (header == NULL || data == NULL)
00084 PANIC ("couldn't allocate buffers");
00085
00086
00087 src = block_get_role (BLOCK_SCRATCH);
00088 if (src == NULL)
00089 PANIC ("couldn't open scratch device");
00090
00091 printf ("Extracting ustar archive from %s into file system...\n",
00092 block_name (src));
00093
00094 for (;;)
00095 {
00096 const char *file_name;
00097 const char *error;
00098 enum ustar_type type;
00099 int size;
00100
00101
00102 block_read (src, sector++, header);
00103 error = ustar_parse_header (header, &file_name, &type, &size);
00104 if (error != NULL)
00105 PANIC ("%s: bad ustar header in sector %"PRDSNu" (%s)",
00106 block_name (src), sector - 1, error);
00107
00108 if (type == USTAR_EOF)
00109 {
00110
00111 break;
00112 }
00113 else if (type == USTAR_DIRECTORY)
00114 printf ("ignoring directory %s\n", file_name);
00115 else if (type == USTAR_REGULAR)
00116 {
00117 struct file *dst;
00118
00119 printf ("Putting '%s' into the file system...\n", file_name);
00120
00121
00122 if (!filesys_create (file_name, size))
00123 PANIC ("%s: create failed", file_name);
00124 dst = filesys_open (file_name);
00125 if (dst == NULL)
00126 PANIC ("%s: open failed", file_name);
00127
00128
00129 while (size > 0)
00130 {
00131 int chunk_size = (size > BLOCK_SECTOR_SIZE
00132 ? BLOCK_SECTOR_SIZE
00133 : size);
00134 block_read (src, sector++, data);
00135 if (file_write (dst, data, chunk_size) != chunk_size)
00136 PANIC ("%s: write failed with %"PROTd" bytes unwritten",
00137 file_name, size);
00138 size -= chunk_size;
00139 }
00140
00141
00142 file_close (dst);
00143 }
00144 }
00145
00146
00147
00148
00149
00150 printf ("Erasing ustar archive...\n");
00151 memset (header, 0, BLOCK_SECTOR_SIZE);
00152 block_write (src, 0, header);
00153 block_write (src, 1, header);
00154
00155 free (data);
00156 free (header);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void
00168 fsutil_append (char **argv)
00169 {
00170 static block_sector_t sector = 0;
00171
00172 const char *file_name = argv[1];
00173 void *buffer;
00174 struct file *src;
00175 struct block *dst;
00176 off_t size;
00177
00178 printf ("Getting '%s' from the file system...\n", file_name);
00179
00180
00181 buffer = malloc (BLOCK_SECTOR_SIZE);
00182 if (buffer == NULL)
00183 PANIC ("couldn't allocate buffer");
00184
00185
00186 src = filesys_open (file_name);
00187 if (src == NULL)
00188 PANIC ("%s: open failed", file_name);
00189 size = file_length (src);
00190
00191
00192 dst = block_get_role (BLOCK_SCRATCH);
00193 if (dst == NULL)
00194 PANIC ("couldn't open scratch device");
00195
00196
00197 if (!ustar_make_header (file_name, USTAR_REGULAR, size, buffer))
00198 PANIC ("%s: can't get from file system (name too long)", file_name);
00199 block_write (dst, sector++, buffer);
00200
00201
00202 while (size > 0)
00203 {
00204 int chunk_size = size > BLOCK_SECTOR_SIZE ? BLOCK_SECTOR_SIZE : size;
00205 if (sector >= block_size (dst))
00206 PANIC ("%s: out of space on scratch device", file_name);
00207 if (file_read (src, buffer, chunk_size) != chunk_size)
00208 PANIC ("%s: read failed with %"PROTd" bytes unread", file_name, size);
00209 memset (buffer + chunk_size, 0, BLOCK_SECTOR_SIZE - chunk_size);
00210 block_write (dst, sector++, buffer);
00211 size -= chunk_size;
00212 }
00213
00214
00215
00216
00217 memset (buffer, 0, BLOCK_SECTOR_SIZE);
00218 block_write (dst, sector, buffer);
00219 block_write (dst, sector, buffer + 1);
00220
00221
00222 file_close (src);
00223 free (buffer);
00224 }