Change -cp option to -ci ("copy in").
[pintos-anon] / src / filesys / fsutil.c
1 #include "filesys/fsutil.h"
2 #include <debug.h>
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "filesys/file.h"
8 #include "filesys/filesys.h"
9 #include "threads/mmu.h"
10 #include "threads/palloc.h"
11
12 /* Destination filename and size for copy-in operations. */
13 char *fsutil_copyin_file;
14 int fsutil_copyin_size;
15
16 /* Source filename for copy-out operations. */
17 char *fsutil_copyout_file;
18
19 /* Name of a file print to print to console. */
20 char *fsutil_print_file;
21
22 /* Name of a file to delete. */
23 char *fsutil_remove_file;
24
25 /* List all files in the filesystem to the system console? */
26 bool fsutil_list_files;
27
28 /* Dump full contents of filesystem to the system console? */
29 bool fsutil_dump_filesys;
30
31 /* Copies from the "scratch" disk, hdc or hd1:0,
32    to a file named FILENAME in the filesystem.
33    The file will be SIZE bytes in length. */
34 static void
35 copy_in (const char *filename, off_t size) 
36 {
37   struct disk *src;
38   struct file *dst;
39   disk_sector_t sector;
40   void *buffer;
41
42   /* Open source disk. */
43   src = disk_get (1, 0);
44   if (src == NULL)
45     PANIC ("couldn't open source disk (hdc or hd1:0)");
46   if (size > (off_t) disk_size (src) * DISK_SECTOR_SIZE)
47     PANIC ("source disk is too small for %lld-byte file",
48            (unsigned long long) size);
49   
50   /* Create destination file. */
51   if (!filesys_create (filename, size))
52     PANIC ("%s: create failed", filename);
53   dst = filesys_open (filename);
54   if (dst == NULL)
55     PANIC ("%s: open failed", filename);
56
57   /* Do copy. */
58   buffer = palloc_get (PAL_ASSERT);
59   sector = 0;
60   while (size > 0)
61     {
62       int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
63       disk_read (src, sector++, buffer);
64       if (file_write (dst, buffer, chunk_size) != chunk_size)
65         PANIC ("%s: write failed with %lld bytes unwritten",
66                filename, (unsigned long long) size);
67       size -= chunk_size;
68     }
69   palloc_free (buffer);
70
71   file_close (dst);
72 }
73
74 /* Copies FILENAME from the file system to the scratch disk.
75    The first four bytes of the first sector in the disk
76    receive the file's size in bytes as a little-endian integer.
77    The second and subsequent sectors receive the file's data. */
78 static void
79 copy_out (const char *filename) 
80 {
81   void *buffer;
82   struct file *src;
83   struct disk *dst;
84   off_t size;
85   disk_sector_t sector;
86
87   buffer = palloc_get (PAL_ASSERT | PAL_ZERO);
88
89   /* Open source file. */
90   src = filesys_open (filename);
91   if (src == NULL)
92     PANIC ("%s: open failed", filename);
93   size = file_length (src);
94
95   /* Open target disk. */
96   dst = disk_get (1, 0);
97   if (dst == NULL)
98     PANIC ("couldn't open target disk (hdc or hd1:0)");
99   if (size + DISK_SECTOR_SIZE > (off_t) disk_size (dst) * DISK_SECTOR_SIZE)
100     PANIC ("target disk is too small for %lld-byte file",
101            (unsigned long long) size);
102   
103   /* Write size to sector 0. */
104   *(uint32_t *) buffer = size;
105   disk_write (dst, 0, buffer);
106   
107   /* Do copy. */
108   sector = 1;
109   while (size > 0) 
110     {
111       int chunk_size = size > DISK_SECTOR_SIZE ? DISK_SECTOR_SIZE : size;
112       if (file_read (src, buffer, chunk_size) != chunk_size)
113         PANIC ("%s: read failed with %lld bytes unread",
114                filename, (unsigned long long) size);
115       disk_write (dst, sector++, buffer);
116       size -= chunk_size;
117     }
118   palloc_free (buffer);
119
120   file_close (src);
121 }
122
123 /* Executes the filesystem operations described by the variables
124    declared in fsutil.h. */
125 void
126 fsutil_run (void) 
127 {
128   if (fsutil_copyin_file != NULL) 
129     copy_in (fsutil_copyin_file, fsutil_copyin_size);
130
131   if (fsutil_copyout_file != NULL)
132     copy_out (fsutil_copyout_file);
133
134   if (fsutil_print_file != NULL)
135     fsutil_print (fsutil_print_file);
136
137   if (fsutil_remove_file != NULL) 
138     {
139       if (filesys_remove (fsutil_remove_file))
140         printf ("%s: removed\n", fsutil_remove_file);
141       else
142         PANIC ("%s: remove failed\n", fsutil_remove_file);
143     }
144
145   if (fsutil_list_files)
146     filesys_list ();
147
148   if (fsutil_dump_filesys)
149     filesys_dump ();
150 }
151
152 /* Prints the contents of file FILENAME to the system console as
153    hex and ASCII. */
154 void
155 fsutil_print (const char *filename) 
156 {
157   struct file *file;
158   char *buffer;
159
160   file = filesys_open (filename);
161   if (file == NULL)
162     PANIC ("%s: open failed", filename);
163   buffer = palloc_get (PAL_ASSERT);
164   for (;;) 
165     {
166       off_t n = file_read (file, buffer, PGSIZE);
167       if (n == 0)
168         break;
169
170       hex_dump (buffer, n, true);
171     }
172   palloc_free (buffer);
173   file_close (file);
174 }