mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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:
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user