[OpenBIOS] r632 - trunk/openbios-devel/fs/ext2

svn at openbios.org svn at openbios.org
Sun Nov 22 11:07:23 CET 2009


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 at 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,




More information about the OpenBIOS mailing list