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>



git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@632 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Laurent Vivier
2009-11-22 10:07:23 +00:00
parent 7c3091927c
commit 62e794e351

View File

@@ -9,6 +9,15 @@
#include "libext2.h" #include "libext2.h"
#include "ext2_utils.h" #include "ext2_utils.h"
#include "openbios/fs.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 static void
umount( fs_ops_t *fs ) umount( fs_ops_t *fs )
@@ -18,23 +27,110 @@ umount( fs_ops_t *fs )
ext2_umount( volume ); 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 * static file_desc_t *
open_path( fs_ops_t *fs, const char *path ) open_path( fs_ops_t *fs, const char *path )
{ {
ext2_VOLUME *volume = (ext2_VOLUME *)fs->fs_data; 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 * static char *
get_path( file_desc_t *fd, char *buf, int size ) 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; return buf;
} }
@@ -42,25 +138,35 @@ get_path( file_desc_t *fd, char *buf, int size )
static int static int
file_lseek( file_desc_t *fd, off_t offs, int whence ) 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 static void
file_close( file_desc_t *fd ) 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 static int
file_read( file_desc_t *fd, void *buf, size_t count ) 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 * static const char *
@@ -70,6 +176,7 @@ get_fstype( fs_ops_t *fs)
} }
static const fs_ops_t ext2_ops = { static const fs_ops_t ext2_ops = {
.dir = dir_fs,
.close_fs = umount, .close_fs = umount,
.open_path = open_path, .open_path = open_path,