Author: laurent Date: 2009-11-22 11:07:23 +0100 (Sun, 22 Nov 2009) New Revision: 632
Modified: trunk/openbios-devel/fs/ext2/ext2_fs.c Log: Implements dir method for ext2 filesystem.
0 > dir hd:3,\ 4096 2009-08-05 22:20:53 .\ 4096 2009-08-05 22:20:53 ..\ 16384 2009-02-20 10:56:01 lost+found\ 4096 2009-02-20 10:56:59 boot\ 4096 2009-11-10 21:44:03 etc\ 4096 2009-02-20 10:57:14 media\ 11 2009-02-20 10:57:14 cdrom 4096 2007-03-07 23:22:28 selinux\ 4096 2009-02-20 11:12:18 var\ 4096 2009-02-20 11:12:19 usr\ 4096 2008-05-21 08:44:38 sys\ 12288 2009-08-05 22:30:50 lib\ 4096 2009-08-05 22:31:05 sbin\ 4096 2009-02-20 13:00:26 bin\ 40960 2009-02-20 14:32:18 dev\ 4096 2009-02-20 14:30:57 home\ 4096 2006-10-28 13:49:35 mnt\ 4096 2006-10-28 13:49:35 proc\ 4096 2009-05-18 12:40:32 root\ 4096 2009-11-10 21:44:15 tmp\ 4096 2009-02-20 12:30:21 lib64\ 4096 2009-02-20 11:12:17 srv\ 4096 2009-02-20 11:12:18 opt\ 4096 2009-02-20 11:12:18 initrd\ 5349268 2009-02-20 11:51:46 initrd.img-2.6.18-6-powerpc 4405754 2008-12-13 09:58:03 vmlinux-2.6.18-6-powerpc
Signed-off-by: Laurent Vivier Laurent@vivier.eu
Modified: trunk/openbios-devel/fs/ext2/ext2_fs.c =================================================================== --- trunk/openbios-devel/fs/ext2/ext2_fs.c 2009-11-22 10:03:00 UTC (rev 631) +++ trunk/openbios-devel/fs/ext2/ext2_fs.c 2009-11-22 10:07:23 UTC (rev 632) @@ -9,7 +9,16 @@ #include "libext2.h" #include "ext2_utils.h" #include "openbios/fs.h" +#include "libc/vsprintf.h"
+typedef struct { + enum { FILE, DIR } type; + union { + ext2_FILE *file; + ext2_DIR *dir; + }; +} ext2_COMMON; + static void umount( fs_ops_t *fs ) { @@ -18,49 +27,146 @@ ext2_umount( volume ); }
+static const int days_month[12] = + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +static const int days_month_leap[12] = + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +static inline int is_leap(int year) +{ + return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); +} + +static void +print_date(time_t sec) +{ + unsigned int second, minute, hour, month, day, year; + int current; + const int *days; + + second = sec % 60; + sec /= 60; + + minute = sec % 60; + sec /= 60; + + hour = sec % 24; + sec /= 24; + + year = sec * 100 / 36525; + sec -= year * 36525 / 100; + year += 1970; + + days = is_leap(year) ? days_month_leap : days_month; + + current = 0; + month = 0; + while (month < 12) { + if (sec <= current + days[month]) { + break; + } + current += days[month]; + month++; + } + month++; + + day = sec - current + 1; + + forth_printf("%d-%02d-%02d %02d:%02d:%02d ", + year, month, day, hour, minute, second); +} + +static void +dir_fs ( file_desc_t *fd) +{ + ext2_COMMON *common = (ext2_COMMON *)fd; + struct ext2_dir_entry_2 *entry; + struct ext2_inode inode; + + if (common->type != DIR) + return; + + forth_printf("\n"); + while ( (entry = ext2_readdir(common->dir)) ) { + ext2_get_inode(common->dir->volume, entry->inode, &inode); + forth_printf("% 10d ", inode.i_size); + print_date(inode.i_mtime); + if (S_ISDIR(inode.i_mode)) + forth_printf("%s\\n", entry->name); + else + forth_printf("%s\n", entry->name); + } +} + static file_desc_t * open_path( fs_ops_t *fs, const char *path ) { ext2_VOLUME *volume = (ext2_VOLUME *)fs->fs_data; - ext2_FILE *file; + ext2_COMMON *common;
- file = ext2_open(volume, path); + common = (ext2_COMMON*)malloc(sizeof(*common)); + if (common == NULL) + return NULL;
- return (file_desc_t *)file; + common->dir = ext2_opendir(volume, path); + if (common->dir == NULL) { + common->file = ext2_open(volume, path); + if (common->file == NULL) { + free(common); + return NULL; + } + common->type = FILE; + return (file_desc_t *)common; + } + common->type = DIR; + return (file_desc_t *)common; }
static char * get_path( file_desc_t *fd, char *buf, int size ) { - ext2_FILE *file = (ext2_FILE *)fd; + ext2_COMMON *common =(ext2_COMMON *)fd;
- strncpy(buf, file->path, size); + if (common->type != FILE) + return NULL;
+ strncpy(buf, common->file->path, size); + return buf; }
static int file_lseek( file_desc_t *fd, off_t offs, int whence ) { - ext2_FILE *file = (ext2_FILE *)fd; + ext2_COMMON *common =(ext2_COMMON *)fd;
- return ext2_lseek(file, offs, whence); + if (common->type != FILE) + return -1; + + return ext2_lseek(common->file, offs, whence); }
static void file_close( file_desc_t *fd ) { - ext2_FILE *file = (ext2_FILE *)fd; + ext2_COMMON *common =(ext2_COMMON *)fd;
- ext2_close(file); + if (common->type == FILE) + ext2_close(common->file); + else if (common->type == DIR) + ext2_closedir(common->dir); + free(common); }
static int file_read( file_desc_t *fd, void *buf, size_t count ) { - ext2_FILE *file = (ext2_FILE *)fd; + ext2_COMMON *common =(ext2_COMMON *)fd;
- return ext2_read(file, buf, count); + if (common->type != FILE) + return -1; + + return ext2_read(common->file, buf, count); }
static const char * @@ -70,6 +176,7 @@ }
static const fs_ops_t ext2_ops = { + .dir = dir_fs, .close_fs = umount,
.open_path = open_path,