Add the cd stuff
[tfsprogs.git] / mktfs.c
blob0fe91a7381ac72162f534ed951298b4f3c4476d3
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <malloc.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
10 #include "tfs.h"
11 #include "file.h"
12 #include "dirent.h"
14 /* From ext2fsprogs */
17 static void mark_used_blocks(struct tfs_sb_info *sbi)
19 int i = 0;
20 char *buf = malloc(sbi->s_block_size);
22 memset(buf, 0, sbi->s_block_size);
23 for (; i < sbi->s_data_area; i++)
24 set_bit(buf, i);
25 tfs_bwrite(sbi, sbi->s_block_bitmap, buf);
28 static int root_init(struct tfs_sb_info *sbi)
30 int res = 0;
31 int dirty = 0;
32 struct inode *root = tfs_root_init(sbi);
34 if (!root) {
35 printf("ERROR: failed to get root inode!\n");
36 res = -1;
37 goto out_nofree;
40 res = tfs_add_entry(sbi, root, ".", root->i_ino, &dirty);
41 if (res == -1) {
42 TFS_DEBUG("trying to add '.' under %s failed!\n", "/");
43 goto out;
46 res = tfs_add_entry(sbi, root, "..", root->i_ino, &dirty);
47 if (res == -1) {
48 TFS_DEBUG("trying to add .. under %s failed!\n", "/");
49 goto out;
52 if (dirty)
53 tfs_iwrite(sbi, root);
55 out:
56 free_inode(root);
57 out_nofree:
58 return res;
61 struct tfs_sb_info * tfs_mkfs(char *image, uint32_t offset)
63 struct tfs_super_block sb;
64 struct tfs_sb_info *sbi;
65 int block_size;
66 int block_bitmap_count, inode_bitmap_count, inode_table_count;
67 uint32_t fs_size;
69 fs_size = open_fs(image);
71 sbi = malloc(sizeof(*sbi));
72 if (!sbi) {
73 printf("malloc for sbi failed!\n");
74 return NULL;
77 memset(&sb, 0, sizeof sb);
78 memset(sbi, 0, sizeof(*sbi));
79 sb.s_magic = TFS_MAGIC;
80 sb.s_block_shift = sbi->s_block_shift = 9; /* 512 Bytes */
81 sbi->s_block_size = block_size = 1 << sb.s_block_shift;
82 sb.s_blocks_count = sbi->s_blocks_count = fs_size / block_size;
85 /* A half of blocks count */
86 sb.s_inodes_count = sbi->s_inodes_count = sb.s_blocks_count / 2;
88 sbi->s_block_bitmap_count = block_bitmap_count = roundup(sb.s_blocks_count, (block_size * 8));
89 sbi->s_inode_bitmap_count = inode_bitmap_count = roundup(sb.s_inodes_count, (block_size * 8));
90 sbi->s_inode_table_count = inode_table_count = sb.s_inodes_count * sizeof(struct tfs_inode) / block_size;
92 sb.s_inode_bitmap = sbi->s_inode_bitmap = 0;
93 sb.s_block_bitmap = sbi->s_block_bitmap = inode_bitmap_count;
94 sb.s_inode_table = sbi->s_inode_table = sb.s_block_bitmap + block_bitmap_count;
95 sb.s_data_area = sbi->s_data_area = sb.s_inode_table + inode_table_count;
97 /* Skip the boot sector and super block sector */
98 sb.s_offset = sbi->s_offset = offset + 2;
100 sb.s_free_inodes_count = sbi->s_free_inodes_count = sb.s_inodes_count;
101 sb.s_free_blocks_count = sbi->s_free_blocks_count = sb.s_blocks_count - sb.s_data_area;
103 sbi->s_inodes_per_block = sbi->s_block_size / sizeof(struct tfs_inode);
106 mark_used_blocks(sbi);
108 cache_init(sbi);
109 root_init(sbi);
111 /* Write the suber block back to image */
112 write_sector(sbi->s_offset - 1, &sb, 1);
114 return sbi;
117 static char *get_full_path(char *filename)
119 char *full = malloc(strlen(filename) + 2);
121 strcpy(full, "/");
122 strcat(full, filename);
124 return full;
128 struct file * tfs_file_open(struct tfs_sb_info *sbi, char *filename)
130 struct file *fobj;
131 char *file = filename;
133 fobj = tfs_open(sbi, file);
134 if (!fobj) {
135 printf("tfs_open: open file %s error!\n", filename);
136 return NULL;
139 return fobj;
142 void tfs_cd(struct tfs_sb_info *sbi, char *dst_dir)
144 DIR *old = this_dir;
146 if (*dst_dir) {
147 this_dir = tfs_opendir(sbi, dst_dir);
148 if (!this_dir) {
149 printf("cd: %s: no such directory\n", dst_dir);
150 this_dir = old;
151 return;
154 if (this_dir->dd_dir->inode->i_mode != TFS_DIR) {
155 printf("cd: %s: is not a directory\n", dst_dir);
156 tfs_closedir(this_dir);
157 this_dir = old;
158 } else {
159 tfs_closedir(old);
165 void tfs_cat(struct tfs_sb_info *sbi, char *filename)
167 struct file *file = tfs_file_open(sbi, filename);
168 char buf[1024];
169 int bytes_read;
171 if (!file)
172 return;
173 while ((bytes_read = tfs_read(file, buf, sizeof(buf))) > 0)
174 write(1, buf, bytes_read);
177 void tfs_ls(struct tfs_sb_info *sbi, char *filename)
179 DIR *dir = tfs_opendir(sbi, filename);
180 struct dirent *de;
182 if (!dir) {
183 printf("open dir %s failed!\n", get_full_path(filename));
184 return;
187 if (dir->dd_dir->inode->i_mode == TFS_FILE) {
188 printf("%d\t %s\n", dir->dd_dir->inode->i_ino, filename);
189 tfs_closedir(dir);
190 return;
193 while (de = tfs_readdir(dir)) {
194 printf("%6d\t %s\n", de->d_ino, de->d_name);
195 free(de);
198 tfs_closedir(dir);
201 void cmd_mkdir(struct tfs_sb_info *sbi, char *filename)
203 tfs_mkdir(sbi, filename);
207 void tfs_cp(struct tfs_sb_info *sbi, char *filename)
209 char buf[1024];
210 int count;
211 int fd;
212 int bytes_written;
213 struct file *file;
215 file = tfs_file_open(sbi, filename);
216 if (!file)
217 return;
219 fd = open(filename, O_RDONLY);
220 if (fd < 0) {
221 printf("open file %s error!\n", filename);
222 return;
224 while ((count = read(fd, buf, sizeof(buf))) > 0) {
225 bytes_written = tfs_write(file, buf, count);
226 if (bytes_written == -1)
227 printf("write error!\n");
228 else
229 printf(" == %d bytes written!\n", bytes_written);
232 tfs_close(file);
236 int main(int argc, char *argv[])
238 int size = sizeof(struct tfs_inode);
239 int offset = 0;
240 char cmd[64];
241 struct tfs_sb_info *sbi;
243 #if 0
244 printf("inode size: %d(0x%x)\n", size, size);
246 size = sizeof(struct tfs_dir_entry);
247 printf("dentry size: %d(0x%x)\n", size, size);
249 size = sizeof(struct tfs_super_block);
250 printf("super block size: %d(0x%0x)\n", size, size);
251 #endif
253 if (argc < 3) {
254 printf("Usage: mktfs image offset\n");
255 return 1;
258 sbi = tfs_mkfs(argv[1], offset);
259 if (!sbi) {
260 printf("mkfs failed!\n");
261 return -1;
264 /* init the this_dir */
265 this_dir = tfs_opendir(sbi, "/");
266 if (!this_dir) {
267 printf("reading '/' as this_dir error!\n");
268 return -1;
271 while (1) {
272 char c;
273 char *p = cmd;
274 char *opt;
276 printf("> ");
278 while((c = getchar()) != '\n')
279 *p++ = c;
280 *p = 0;
282 p = cmd;
283 while (*p != ' ' && *p)
284 p++;
285 if (*p) {
286 *p++ = 0;
287 while (*p == ' ')
288 p++;
289 opt = p;
290 } else
291 opt = NULL;
294 if (strcmp(cmd, "cp") == 0) {
295 printf("copying file '%s' ... \n", opt);
296 tfs_cp(sbi, opt);
297 } else if (strcmp(cmd, "cat") == 0) {
298 printf("cating file '%s' ... \n", opt);
299 tfs_cat(sbi, opt);
300 } else if (strcmp(cmd, "cd") == 0) {
301 printf("cd in '%s' ... \n", opt);
302 tfs_cd(sbi, opt);
303 } else if (strcmp(cmd, "ls") == 0) {
304 if (!opt)
305 opt = ".";
306 printf("listing file '%s' ...\n", opt);
307 tfs_ls(sbi, opt);
308 } else if (strcmp(cmd, "mkdir") == 0) {
309 printf("making dir '%s' ... \n", opt);
310 cmd_mkdir(sbi, opt);
311 } else if (strcmp(cmd, "quit") == 0 ||
312 strcmp(cmd, "exit") == 0) {
313 break;
314 } else {
315 printf("unknow command!\n");
319 free(sbi);
321 return 0;