]> git.ozlabs.org Git - yaboot.git/commitdiff
Commit yaboot 1.3.4-pre1
authorEthan Benson <erbenson@alaska.net>
Mon, 25 Mar 2002 15:13:19 +0000 (15:13 +0000)
committerEthan Benson <erbenson@alaska.net>
Mon, 25 Mar 2002 15:13:19 +0000 (15:13 +0000)
Commit yaboot 1.3.4-pre1.
git-archimport-id: erbenson@alaska.net--public/yaboot--devel--1.3--patch-5

32 files changed:
ChangeLog
Config [new file with mode: 0644]
Makefile
THANKS
changelog
include/errors.h [new file with mode: 0644]
include/file.h
include/fs.h
include/gui.h [deleted file]
include/prom.h
include/string.h
include/video.h [deleted file]
include/xfs/xfs.h [new file with mode: 0644]
include/yaboot.h
lib/malloc.c
second/cfg.c
second/file.c
second/fs.c
second/fs_ext2.c
second/fs_iso.c
second/fs_of.c
second/fs_reiserfs.c
second/fs_xfs.c [new file with mode: 0644]
second/gui/colormap.c [deleted file]
second/gui/effects.c [deleted file]
second/gui/pcx.c [deleted file]
second/gui/video.c [deleted file]
second/partition.c
second/prom.c
second/yaboot.c
util/addnote.c
ybin/ybin

index e517c1e11e7bafb674ec7637250daf1807fc7f27..1052750ecf41e2d5312ee339bb6ab51796bc4d2d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,44 @@
 # tag: automatic-ChangeLog--erbenson@alaska.net--public/yaboot--devel--1.3
 #
 
+2002-03-25 15:13:19 GMT        Ethan Benson <erbenson@alaska.net>      patch-5
+
+    Summary:
+      Commit yaboot 1.3.4-pre1
+    Revision:
+      yaboot--devel--1.3--patch-5
+
+    Commit yaboot 1.3.4-pre1.
+
+    new files:
+     include/xfs/.arch-ids/=id include/xfs/.arch-ids/xfs.h.id
+     include/.arch-ids/errors.h.id second/.arch-ids/fs_xfs.c.id
+     .arch-ids/Config.id include/xfs/xfs.h include/errors.h
+     second/fs_xfs.c Config
+
+    removed files:
+     include/.arch-ids/gui.h.id include/.arch-ids/video.h.id
+     second/gui/.arch-ids/=id second/gui/.arch-ids/colormap.c.id
+     second/gui/.arch-ids/effects.c.id
+     second/gui/.arch-ids/pcx.c.id second/gui/.arch-ids/video.c.id
+     include/gui.h include/video.h second/gui/colormap.c
+     second/gui/effects.c second/gui/pcx.c second/gui/video.c
+
+    modified files:
+     ChangeLog Makefile THANKS changelog include/file.h
+     include/fs.h include/prom.h include/string.h include/yaboot.h
+     lib/malloc.c second/cfg.c second/file.c second/fs.c
+     second/fs_ext2.c second/fs_iso.c second/fs_of.c
+     second/fs_reiserfs.c second/partition.c second/prom.c
+     second/yaboot.c util/addnote.c ybin/ybin
+
+    new directories:
+     include/xfs/.arch-ids include/xfs
+
+    removed directories:
+     second/gui/.arch-ids second/gui
+
+
 2002-03-25 14:50:10 GMT        Ethan Benson <erbenson@alaska.net>      patch-4
 
     Summary:
diff --git a/Config b/Config
new file mode 100644 (file)
index 0000000..0d03fa0
--- /dev/null
+++ b/Config
@@ -0,0 +1,30 @@
+# Configuration variables, y == enabled n == disabled
+
+# Enable text color configurability: the fgcolor= and bgcolor= config
+# options (see yaboot.conf(5))
+#
+CONFIG_COLOR_TEXT      :=      y
+
+# Enable colormap setup.  Required on PowerMacs for text coloring to
+# work right.
+#
+CONFIG_SET_COLORMAP    :=      y
+
+# Enable md5 passwords, allows value of password= to be an MD5 hash as
+# well as cleartext.  When set to n only cleartext passwords are accepted.
+#
+USE_MD5_PASSWORDS      :=      y
+
+# Filesystem support
+#
+# Enable SGI XFS
+#
+CONFIG_FS_XFS          :=      y
+
+# Enable ReiserFS
+#
+CONFIG_FS_REISERFS     :=      y
+
+# Local Variables:
+# mode: makefile
+# End:
index c9a55e2dd5175db8db7b63997446aa5401938ad2..4b2274e0449f9b9370cd03c4b326d22b22963137 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,22 +1,17 @@
-## Configuration section
+## Setup
 
-VERSION = 1.3.3
-# Debug mode (verbose)
+include Config
+
+VERSION = 1.3.4pre1
+# Debug mode (spam/verbose)
 DEBUG = 0
+# make install vars
 ROOT =
 PREFIX = usr/local
 MANDIR = man
+# command used to get root (needed for tarball creation)
 GETROOT = fakeroot
 
-# Enable text colors
-CONFIG_COLOR_TEXT = y
-# Enable colormap setup
-CONFIG_SET_COLORMAP = y
-# Enable splash screen
-CONFIG_SPLASH_SCREEN = n
-# Enable md5 passwords
-USE_MD5_PASSWORDS = y
-
 # We use fixed addresses to avoid overlap when relocating
 # and other trouble with initrd
 
@@ -33,29 +28,33 @@ KERNELADDR  = 0x01400000
 #
 CROSS = 
 
-# The flags for the target compiler.
+# The flags for the yaboot binary.
 #
-CFLAGS = -Os -nostdinc -Wall -isystem `gcc -print-file-name=include` -fsigned-char
-CFLAGS += -DVERSION=\"${VERSION}\"     #"
-CFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG)
-CFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE)
-CFLAGS += -DKERNELADDR=$(KERNELADDR)
-CFLAGS += -I ./include
+YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `gcc -print-file-name=include` -fsigned-char
+YBCFLAGS += -DVERSION=\"${VERSION}\"   #"
+YBCFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG)
+YBCFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE)
+YBCFLAGS += -DKERNELADDR=$(KERNELADDR)
+YBCFLAGS += -I ./include
 
 ifeq ($(CONFIG_COLOR_TEXT),y)
-CFLAGS += -DCONFIG_COLOR_TEXT
+YBCFLAGS += -DCONFIG_COLOR_TEXT
 endif
 
 ifeq ($(CONFIG_SET_COLORMAP),y)
-CFLAGS += -DCONFIG_SET_COLORMAP
+YBCFLAGS += -DCONFIG_SET_COLORMAP
 endif
 
-ifeq ($(CONFIG_SPLASH_SCREEN),y)
-CFLAGS += -DCONFIG_SPLASH_SCREEN
+ifeq ($(USE_MD5_PASSWORDS),y)
+YBCFLAGS += -DUSE_MD5_PASSWORDS
 endif
 
-ifeq ($(USE_MD5_PASSWORDS),y)
-CFLAGS += -DUSE_MD5_PASSWORDS
+ifeq ($(CONFIG_FS_XFS),y)
+YBCFLAGS += -DCONFIG_FS_XFS
+endif
+
+ifeq ($(CONFIG_FS_REISERFS),y)
+YBCFLAGS += -DCONFIG_FS_REISERFS
 endif
 
 # Link flags
@@ -65,43 +64,50 @@ LFLAGS = -Ttext $(TEXTADDR) -Bstatic
 # Libraries
 #
 LLIBS = lib/libext2fs.a
-#LLIBS = -l ext2fs
+
+# For compiling userland utils
+#
+UCFLAGS = -Os $(CFLAGS) -Wall -I/usr/include
 
 # For compiling build-tools that run on the host.
 #
 HOSTCC = gcc
-HOSTCFLAGS = -I/usr/include $(CFLAGS)
+HOSTCFLAGS = -O2 $(CFLAGS) -Wall -I/usr/include
 
 ## End of configuration section
 
 OBJS = second/crt0.o second/yaboot.o second/cache.o second/prom.o second/file.o \
        second/partition.o second/fs.o second/cfg.o second/setjmp.o second/cmdline.o \
-       second/fs_of.o second/fs_ext2.o second/fs_reiserfs.o second/fs_iso.o second/iso_util.o \
+       second/fs_of.o second/fs_ext2.o second/fs_iso.o second/iso_util.o \
        lib/nosys.o lib/string.o lib/strtol.o lib/vsprintf.o lib/ctype.o lib/malloc.o lib/strstr.o
 
-ifeq ($(CONFIG_SPLASH_SCREEN),y)
-OBJS += second/gui/effects.o second/gui/colormap.o second/gui/video.o second/gui/pcx.o
-endif
-
 ifeq ($(USE_MD5_PASSWORDS),y)
 OBJS += second/md5.o
 endif
 
+ifeq ($(CONFIG_FS_XFS),y)
+OBJS += second/fs_xfs.o
+endif
+
+ifeq ($(CONFIG_FS_REISERFS),y)
+OBJS += second/fs_reiserfs.o
+endif
+
 CC = $(CROSS)gcc
 LD = $(CROSS)ld
 AS = $(CROSS)as
 OBJCOPY = $(CROSS)objcopy
 
-all: yaboot addnote mkofboot
-
 lgcc = `$(CC) -print-libgcc-file-name`
 
+all: yaboot addnote mkofboot
+
 yaboot: $(OBJS)
        $(LD) $(LFLAGS) $(OBJS) $(LLIBS) $(lgcc) -o second/$@
        chmod -x second/yaboot
 
 addnote:
-       $(HOSTCC) $(HOSTCFLAGS) -o util/addnote util/addnote.c
+       $(CC) $(UCFLAGS) -o util/addnote util/addnote.c
 
 elfextract:
        $(HOSTCC) $(HOSTCFLAGS) -o util/elfextract util/elfextract.c
@@ -110,10 +116,10 @@ mkofboot:
        ln -sf ybin ybin/mkofboot
 
 %.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $<
+       $(CC) $(YBCFLAGS) -c -o $@ $<
 
 %.o: %.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__  -c -o $@ $<
+       $(CC) $(YBCFLAGS) -D__ASSEMBLY__  -c -o $@ $<
 
 dep:
        makedepend -Iinclude *.c lib/*.c util/*.c gui/*.c
diff --git a/THANKS b/THANKS
index 630a169094d3d9f1e438d4844c8926fcc04dd2a2..f81e09493983c32814cdb86cd6a2fdf5e1448a2c 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -2,6 +2,7 @@ In no particular order:
 
  * Daniel Jacobowitz <dan@debian.org> for Debian packaging, advice and busybox help.
  * Benjamin Herrenschmidt <benh@kernel.crashing.org> for yaboot and great work on the kernel.
+ * Colin Walters <walters@verbum.org> for advice, help with XFS and general code auditing.
  * Charles Stevenson <csteven@newhope.terraplex.com> for adding color config support to yaboot.
  * Chris Emerson <cemerson@chiark.greenend.org.uk> for the Forth code in ofboot.
  * iNOUE Koich! <inoue@ma.ns.musashi-tech.ac.jp> for advice and help [re]writing ofboot's Forth code.
index 8166c519b4adb775e853b2d571548f26beafc4da..b4aaafae28832aa8d26a84020f43cef84b07431c 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,3 +1,27 @@
+2001-10-09  Ethan Benson  <erbenson@alaska.net>
+
+       * Version 1.3.4-pre1
+
+       * yaboot:
+         - Add SGI XFS filesystem support.
+         - Rewrite OpenFirmware device path parsing code.  This fixes
+           many bugs and inconsistencies in yaboot's file loading.
+         - Fix OpenFirmware filesystem support to automatically convert
+           path separator from / to \.  CDROM authors no longer need to use
+           hacks like image=\\install\\powermac\\vmlinux.
+         - Fix kernel loading on some systems.
+         - Allow for getting files from tftp server that does not run a
+           bootpd/dhcpd.
+         - Fix a great deal of incorrect format strings which could cause
+           yaboot crashes.
+         - Fix all filesystems to properly return error conditions, and
+           report those error conditions (instead of just saying `image not
+           found').
+         - Add `help' command to yaboot which prints out basic usage information.
+         - General cruft removal and code cleanup.
+
+       * Makefile cleanup, make filesystems configurable.
+       
 2001-09-25  Ethan Benson  <erbenson@alaska.net>
 
        * Version 1.3.3
diff --git a/include/errors.h b/include/errors.h
new file mode 100644 (file)
index 0000000..c4950e5
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  errors.h - Definitions of error numbers returned by filesystems
+ *
+ *  Copyright (C) 2001  Ethan Benson
+ *
+ *  Copyright (C) 1999 Benjamin Herrenschmidt
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Simple error codes */
+#define FILE_ERR_OK             0
+#define FILE_ERR_EOF            -1
+#define FILE_ERR_NOTFOUND       -2
+#define FILE_CANT_SEEK          -3
+#define FILE_IOERR              -4
+#define FILE_BAD_PATH           -5
+#define FILE_ERR_BAD_TYPE       -6
+#define FILE_ERR_NOTDIR         -7
+#define FILE_ERR_BAD_FSYS       -8
+#define FILE_ERR_SYMLINK_LOOP   -9
+#define FILE_ERR_LENGTH         -10
+#define FILE_ERR_FSBUSY         -11
+#define FILE_ERR_BADDEV         -12
index c68d84f66eeec8e0cbd08efd7806fc2923450a79..03c5c6fe3e40877d317237b17196503384cb8e7a 100644 (file)
@@ -31,18 +31,6 @@ struct boot_file_t;
 
 #define FILE_MAX_PATH          1024
 
-/* Simple error codes */
-#define FILE_ERR_OK            0
-#define FILE_ERR_EOF           -1
-#define FILE_ERR_NOTFOUND      -2
-#define FILE_CANT_SEEK         -3
-#define FILE_IOERR             -4
-#define FILE_BAD_PATH          -5
-#define FILE_ERR_BAD_TYPE       -6
-#define FILE_ERR_BAD_FSYS       -7
-#define FILE_ERR_SYMLINK_LOOP   -8
-#define FILE_ERR_LENGTH         -9
-
 /* Device kind */
 #define FILE_DEVICE_BLOCK      1
 #define FILE_DEVICE_NET                2
@@ -73,9 +61,15 @@ struct boot_file_t {
 //     unsigned int    part_count;
 };
 
-extern int open_file(  const struct boot_fspec_t*      spec,
-                       struct boot_file_t*             file);
+extern int
+open_file(const struct boot_fspec_t*   spec,
+         struct boot_file_t*           file);
+
+extern int
+parse_device_path(char *imagepath, char *defdevice, int defpart,
+                 char *deffile, struct boot_fspec_t *result);
 
+#if 0
 extern int validate_fspec(
                        struct boot_fspec_t*    spec,
                        char*                   default_device,
@@ -84,7 +78,7 @@ extern char *parse_device_path(
                        char*                   of_device,
                        char**                  file_spec,
                        int*                    partition);
-
+#endif
 
 
 #endif
index 3ec59281bfbbb76ed65c7d2a21ad38eae441a7ed..647c37a02d412ab3c13961a962a06d69d79f8a07 100644 (file)
@@ -24,6 +24,8 @@
 #include "partition.h"
 #include "file.h"
 
+int fserrorno;
+
 struct fs_t {
        const char* name;
 
@@ -45,26 +47,33 @@ struct fs_t {
 extern const struct fs_t *fs_of;
 extern const struct fs_t *fs_of_netboot;
 
-const struct fs_t *fs_open( struct boot_file_t *file, const char *dev_name,
-                            struct partition_t *part, const char *file_name );
+const struct fs_t *fs_open(struct boot_file_t *file, const char *dev_name,
+                         struct partition_t *part, const char *file_name);
 
 #if DEBUG
-# define DEBUG_ENTER prom_printf( "--> %s\n", __PRETTY_FUNCTION__ );
+# define DEBUG_ENTER prom_printf( "--> %s\n", __PRETTY_FUNCTION__ )
 # define DEBUG_LEAVE(str) \
-    prom_printf( "<-- %s - %s\n", __PRETTY_FUNCTION__, #str );
+    prom_printf( "<-- %s - %s\n", __PRETTY_FUNCTION__, #str )
+# define DEBUG_LEAVE_F(args...)\
+{\
+    prom_printf( "<-- %s - %d\n", __PRETTY_FUNCTION__, ## args );\
+}
 # define DEBUG_F(fmt, args...)\
 {\
     prom_printf( "    %s - ", __PRETTY_FUNCTION__ );\
     prom_printf( fmt, ## args );\
 }
-# define DEBUG_OPEN DEBUG_F( "dev=%s, part=0x%08lx (%d), file_name=%s\n",\
+# define DEBUG_OPEN DEBUG_F( "dev=%s, part=0x%p (%d), file_name=%s\n",\
                              dev_name, part, part ? part->part_number : -1,\
-                             file_name);
+                             file_name)
+# define DEBUG_SLEEP prom_sleep(3)
 #else
 #define DEBUG_ENTER
 #define DEBUG_LEAVE(x)
+#define DEBUG_LEAVE_F(args...)
 #define DEBUG_F(fmt, args...)
 #define DEBUG_OPEN
+#define DEBUG_SLEEP
 #endif
 
 #endif
diff --git a/include/gui.h b/include/gui.h
deleted file mode 100644 (file)
index c1aaec6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-extern void fxDisplaySplash(struct boot_fspec_t *filespec);
-int fxReadImage(struct boot_file_t *file, unsigned int filesize, void *base);
-
index b217be408c90fd861411020cd97c23260d6979b3..546d082e4a26cf63c719b57895166ebd9b32f23a 100644 (file)
@@ -62,9 +62,17 @@ int prom_getchar ();
 void prom_putchar (char);
 int prom_nbgetchar();
 
+#ifdef __GNUC__
+void prom_vprintf (char *fmt, va_list ap) __attribute__ ((format (printf, 1, 0)));
+void prom_fprintf (prom_handle dev, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+void prom_printf (char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+#else
 void prom_vprintf (char *fmt, va_list ap);
 void prom_fprintf (prom_handle dev, char *fmt, ...);
 void prom_printf (char *fmt, ...);
+#endif
+
+void prom_perror (int error, char *filename);
 void prom_readline (char *prompt, char *line, int len);
 int prom_set_color(prom_handle device, int color, int r, int g, int b);
 
@@ -87,6 +95,7 @@ void prom_setargs (char *args);
 
 void prom_exit ();
 void prom_abort (char *fmt, ...);
+void prom_sleep (int seconds);
 
 int prom_interpret (char *forth);
 
index 6d6577342022e25c7b5b0e7342b1589dd55dd65b..4d2b3c31ed575f35ff405a60d486ebb790c52a8f 100644 (file)
@@ -19,7 +19,7 @@ extern size_t strspn(const char *,const char *);
 extern int strcmp(const char *,const char *);
 extern int strncmp(const char *,const char *,size_t);
 extern int strnicmp(const char *, const char *, size_t);
-extern void *strdup(char *str);
+extern char *strdup(char const *str);
 
 extern void * memset(void *,int,size_t);
 extern void * memcpy(void *,const void *,size_t);
diff --git a/include/video.h b/include/video.h
deleted file mode 100644 (file)
index c5f61b8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __VIDEO_H__
-#define __VIDEO_H__
-
-
-
-#endif
\ No newline at end of file
diff --git a/include/xfs/xfs.h b/include/xfs/xfs.h
new file mode 100644 (file)
index 0000000..51db098
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file
+ *
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#ifndef _BITS_TYPES_H
+typedef signed char    __int8_t;
+typedef unsigned char  __uint8_t;
+typedef short          __int16_t;
+typedef unsigned short __uint16_t;
+typedef int            __int32_t;
+typedef unsigned int   __uint32_t;
+typedef long long      __int64_t;
+typedef unsigned long long __uint64_t;
+#endif
+
+typedef __uint64_t     xfs_ino_t;
+typedef        __uint32_t      xfs_agino_t;
+typedef __int64_t      xfs_daddr_t;
+typedef __int64_t      xfs_off_t;
+typedef __uint8_t      uuid_t[16];
+
+
+/* those are from xfs_types.h */
+
+typedef __uint32_t     xfs_agblock_t;  /* blockno in alloc. group */
+typedef        __uint32_t      xfs_extlen_t;   /* extent length in blocks */
+typedef        __uint32_t      xfs_agnumber_t; /* allocation group number */
+typedef __int32_t      xfs_extnum_t;   /* # of extents in a file */
+typedef __int16_t      xfs_aextnum_t;  /* # extents in an attribute fork */
+typedef        __int64_t       xfs_fsize_t;    /* bytes in a file */
+
+typedef        __uint32_t      xfs_dablk_t;    /* dir/attr block number (in file) */
+typedef        __uint32_t      xfs_dahash_t;   /* dir/attr hash value */
+
+/*
+ * Disk based types:
+ */
+typedef __uint64_t     xfs_dfsbno_t;   /* blockno in filesystem (agno|agbno) */
+typedef __uint64_t     xfs_drfsbno_t;  /* blockno in filesystem (raw) */
+typedef        __uint64_t      xfs_drtbno_t;   /* extent (block) in realtime area */
+typedef        __uint64_t      xfs_dfiloff_t;  /* block number in a file */
+
+typedef        __uint64_t      xfs_fsblock_t;  /* blockno in filesystem (agno|agbno) */
+typedef        __uint64_t      xfs_fileoff_t;  /* block number in a file */
+typedef        __uint64_t      xfs_filblks_t;  /* number of blocks in a file */
+
+
+/* those are from xfs_sb.h */
+
+#define        XFS_SB_MAGIC            0x58465342      /* 'XFSB'*/
+#define        XFS_SB_VERSION_4        4               /* 6.2+ - bitmask version */
+#define        XFS_SB_VERSION_NUMBITS  0x000f
+
+typedef struct xfs_sb
+{
+       __uint32_t      sb_magicnum;    /* magic number == XFS_SB_MAGIC */
+       __uint32_t      sb_blocksize;   /* logical block size, bytes */
+       xfs_drfsbno_t   sb_dblocks;     /* number of data blocks */
+       xfs_drfsbno_t   sb_rblocks;     /* number of realtime blocks */
+       xfs_drtbno_t    sb_rextents;    /* number of realtime extents */
+       uuid_t          sb_uuid;        /* file system unique id */
+       xfs_dfsbno_t    sb_logstart;    /* starting block of log if internal */
+       xfs_ino_t       sb_rootino;     /* root inode number */
+       xfs_ino_t       sb_rbmino;      /* bitmap inode for realtime extents */
+       xfs_ino_t       sb_rsumino;     /* summary inode for rt bitmap */
+       xfs_agblock_t   sb_rextsize;    /* realtime extent size, blocks */
+       xfs_agblock_t   sb_agblocks;    /* size of an allocation group */
+       xfs_agnumber_t  sb_agcount;     /* number of allocation groups */
+       xfs_extlen_t    sb_rbmblocks;   /* number of rt bitmap blocks */
+       xfs_extlen_t    sb_logblocks;   /* number of log blocks */
+       __uint16_t      sb_versionnum;  /* header version == XFS_SB_VERSION */
+       __uint16_t      sb_sectsize;    /* volume sector size, bytes */
+       __uint16_t      sb_inodesize;   /* inode size, bytes */
+       __uint16_t      sb_inopblock;   /* inodes per block */
+       char            sb_fname[12];   /* file system name */
+       __uint8_t       sb_blocklog;    /* log2 of sb_blocksize */
+       __uint8_t       sb_sectlog;     /* log2 of sb_sectsize */
+       __uint8_t       sb_inodelog;    /* log2 of sb_inodesize */
+       __uint8_t       sb_inopblog;    /* log2 of sb_inopblock */
+       __uint8_t       sb_agblklog;    /* log2 of sb_agblocks (rounded up) */
+       __uint8_t       sb_rextslog;    /* log2 of sb_rextents */
+       __uint8_t       sb_inprogress;  /* mkfs is in progress, don't mount */
+       __uint8_t       sb_imax_pct;    /* max % of fs for inode space */
+                                       /* statistics */
+       /*
+        * These fields must remain contiguous.  If you really
+        * want to change their layout, make sure you fix the
+        * code in xfs_trans_apply_sb_deltas().
+        */
+       __uint64_t      sb_icount;      /* allocated inodes */
+       __uint64_t      sb_ifree;       /* free inodes */
+       __uint64_t      sb_fdblocks;    /* free data blocks */
+       __uint64_t      sb_frextents;   /* free realtime extents */
+       /*
+        * End contiguous fields.
+        */
+       xfs_ino_t       sb_uquotino;    /* user quota inode */
+       xfs_ino_t       sb_gquotino;    /* group quota inode */
+       __uint16_t      sb_qflags;      /* quota flags */
+       __uint8_t       sb_flags;       /* misc. flags */
+       __uint8_t       sb_shared_vn;   /* shared version number */
+       xfs_extlen_t    sb_inoalignmt;  /* inode chunk alignment, fsblocks */
+       __uint32_t      sb_unit;        /* stripe or raid unit */
+       __uint32_t      sb_width;       /* stripe or raid width */      
+       __uint8_t       sb_dirblklog;   /* log2 of dir block size (fsbs) */
+        __uint8_t       sb_dummy[7];    /* padding */
+} xfs_sb_t;
+
+
+/* those are from xfs_btree.h */
+
+/*
+ * Long form header: bmap btrees.
+ */
+typedef struct xfs_btree_lblock
+{
+       __uint32_t      bb_magic;       /* magic number for block type */
+       __uint16_t      bb_level;       /* 0 is a leaf */
+       __uint16_t      bb_numrecs;     /* current # of data records */
+       xfs_dfsbno_t    bb_leftsib;     /* left sibling block or NULLDFSBNO */
+       xfs_dfsbno_t    bb_rightsib;    /* right sibling block or NULLDFSBNO */
+} xfs_btree_lblock_t;
+
+/*
+ * Combined header and structure, used by common code.
+ */
+typedef struct xfs_btree_hdr
+{
+       __uint32_t      bb_magic;       /* magic number for block type */
+       __uint16_t      bb_level;       /* 0 is a leaf */
+       __uint16_t      bb_numrecs;     /* current # of data records */
+} xfs_btree_hdr_t;
+
+typedef struct xfs_btree_block
+{
+       xfs_btree_hdr_t bb_h;           /* header */
+       union           {
+               struct  {
+                       xfs_agblock_t   bb_leftsib;
+                       xfs_agblock_t   bb_rightsib;
+               }       s;              /* short form pointers */
+               struct  {
+                       xfs_dfsbno_t    bb_leftsib;
+                       xfs_dfsbno_t    bb_rightsib;
+               }       l;              /* long form pointers */
+       }               bb_u;           /* rest */
+} xfs_btree_block_t;
+
+/* those are from xfs_bmap_btree.h */
+
+/*
+ * Bmap root header, on-disk form only.
+ */
+typedef struct xfs_bmdr_block
+{
+       __uint16_t      bb_level;       /* 0 is a leaf */
+       __uint16_t      bb_numrecs;     /* current # of data records */
+} xfs_bmdr_block_t;
+
+/*
+ * Bmap btree record and extent descriptor.
+ * For 32-bit kernels,
+ *  l0:31 is an extent flag (value 1 indicates non-normal).
+ *  l0:0-30 and l1:9-31 are startoff.
+ *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
+ *  l3:0-20 are blockcount.
+ * For 64-bit kernels,
+ *  l0:63 is an extent flag (value 1 indicates non-normal).
+ *  l0:9-62 are startoff.
+ *  l0:0-8 and l1:21-63 are startblock.
+ *  l1:0-20 are blockcount.
+ */
+
+#define        BMBT_USE_64     1
+
+typedef struct xfs_bmbt_rec_32
+{
+       __uint32_t              l0, l1, l2, l3;
+} xfs_bmbt_rec_32_t;
+typedef struct xfs_bmbt_rec_64
+{
+       __uint64_t              l0, l1;
+} xfs_bmbt_rec_64_t;
+
+#if BMBT_USE_64
+typedef        __uint64_t      xfs_bmbt_rec_base_t;    /* use this for casts */
+typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#else  /* !BMBT_USE_64 */
+typedef        __uint32_t      xfs_bmbt_rec_base_t;    /* use this for casts */
+typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#endif /* BMBT_USE_64 */
+
+/*
+ * Key structure for non-leaf levels of the tree.
+ */
+typedef struct xfs_bmbt_key
+{
+       xfs_dfiloff_t   br_startoff;    /* starting file offset */
+} xfs_bmbt_key_t, xfs_bmdr_key_t;
+
+typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;   /* btree pointer type */
+                                       /* btree block header type */
+typedef        struct xfs_btree_lblock xfs_bmbt_block_t;
+
+
+/* those are from xfs_dir2.h */
+/*
+ * Directory version 2.
+ * There are 4 possible formats:
+ *     shortform
+ *     single block - data with embedded leaf at the end
+ *     multiple data blocks, single leaf+freeindex block
+ *     data blocks, node&leaf blocks (btree), freeindex blocks
+ *
+ *     The shortform format is in xfs_dir2_sf.h.
+ *     The single block format is in xfs_dir2_block.h.
+ *     The data block format is in xfs_dir2_data.h.
+ *     The leaf and freeindex block formats are in xfs_dir2_leaf.h.
+ *     Node blocks are the same as the other version, in xfs_da_btree.h.
+ */
+
+/*
+ * Byte offset in data block and shortform entry.
+ */
+typedef        __uint16_t      xfs_dir2_data_off_t;
+
+/*
+ * Byte offset in a directory.
+ */
+typedef        xfs_off_t               xfs_dir2_off_t;
+
+/* those are from xfs_da_btree.h */
+/*========================================================================
+ * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
+ *========================================================================*/
+
+/*
+ * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
+ *
+ * Is is used to manage a doubly linked list of all blocks at the same
+ * level in the Btree, and to identify which type of block this is.
+ */
+#define        XFS_DIR2_LEAF1_MAGIC    0xd2f1  /* magic number: v2 dirlf single blks */
+#define        XFS_DIR2_LEAFN_MAGIC    0xd2ff  /* magic number: v2 dirlf multi blks */
+
+typedef struct xfs_da_blkinfo {
+       xfs_dablk_t forw;                       /* previous block in list */
+       xfs_dablk_t back;                       /* following block in list */
+       __uint16_t magic;                       /* validity check on block */
+       __uint16_t pad;                         /* unused */
+} xfs_da_blkinfo_t;
+
+/*
+ * This is the structure of the root and intermediate nodes in the Btree.
+ * The leaf nodes are defined above.
+ *
+ * Entries are not packed.
+ *
+ * Since we have duplicate keys, use a binary search but always follow
+ * all match in the block, not just the first match found.
+ */
+
+typedef struct xfs_da_intnode {
+       struct xfs_da_node_hdr {        /* constant-structure header block */
+               xfs_da_blkinfo_t info;  /* block type, links, etc. */
+               __uint16_t count;       /* count of active entries */
+               __uint16_t level;       /* level above leaves (leaf == 0) */
+       } hdr;
+       struct xfs_da_node_entry {
+               xfs_dahash_t hashval;   /* hash value for this descendant */
+               xfs_dablk_t before;     /* Btree block before this key */
+       } btree[1];                     /* variable sized array of keys */
+} xfs_da_intnode_t;
+
+
+/* those are from xfs_dir2_data.h */
+/*
+ * Directory format 2, data block structures.
+ */
+
+/*
+ * Constants.
+ */
+#define        XFS_DIR2_DATA_FREE_TAG  0xffff
+#define        XFS_DIR2_DATA_FD_COUNT  3
+
+/*
+ * Structures.
+ */
+
+/*
+ * Describe a free area in the data block.
+ * The freespace will be formatted as a xfs_dir2_data_unused_t.
+ */
+typedef struct xfs_dir2_data_free {
+       xfs_dir2_data_off_t     offset;         /* start of freespace */
+       xfs_dir2_data_off_t     length;         /* length of freespace */
+} xfs_dir2_data_free_t;
+
+/*
+ * Header for the data blocks.
+ * Always at the beginning of a directory-sized block.
+ * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
+ */
+typedef struct xfs_dir2_data_hdr {
+       __uint32_t              magic;          /* XFS_DIR2_DATA_MAGIC */
+                                               /* or XFS_DIR2_BLOCK_MAGIC */
+       xfs_dir2_data_free_t    bestfree[XFS_DIR2_DATA_FD_COUNT];
+} xfs_dir2_data_hdr_t;
+
+/*
+ * Active entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_entry {
+       xfs_ino_t               inumber;        /* inode number */
+       __uint8_t               namelen;        /* name length */
+       __uint8_t               name[1];        /* name bytes, no null */
+                                               /* variable offset */
+       xfs_dir2_data_off_t     tag;            /* starting offset of us */
+} xfs_dir2_data_entry_t;
+
+/*
+ * Unused entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_unused {
+       __uint16_t              freetag;        /* XFS_DIR2_DATA_FREE_TAG */
+       xfs_dir2_data_off_t     length;         /* total free length */
+                                               /* variable offset */
+       xfs_dir2_data_off_t     tag;            /* starting offset of us */
+} xfs_dir2_data_unused_t;
+
+typedef union {
+       xfs_dir2_data_entry_t   entry;
+       xfs_dir2_data_unused_t  unused;
+} xfs_dir2_data_union_t;
+
+
+/* those are from xfs_dir2_leaf.h */
+/*
+ * Directory version 2, leaf block structures.
+ */
+
+/*
+ * Leaf block header.
+ */
+typedef struct xfs_dir2_leaf_hdr {
+       xfs_da_blkinfo_t        info;           /* header for da routines */
+       __uint16_t              count;          /* count of entries */
+       __uint16_t              stale;          /* count of stale entries */
+} xfs_dir2_leaf_hdr_t;
+
+
+/* those are from xfs_dir2_block.h */
+/*
+ * xfs_dir2_block.h
+ * Directory version 2, single block format structures
+ */
+
+/*
+ * The single block format is as follows:
+ * xfs_dir2_data_hdr_t structure
+ * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
+ * xfs_dir2_leaf_entry_t structures
+ * xfs_dir2_block_tail_t structure
+ */
+
+#define        XFS_DIR2_BLOCK_MAGIC    0x58443242      /* XD2B: for one block dirs */
+
+typedef struct xfs_dir2_block_tail {
+       __uint32_t      count;                  /* count of leaf entries */
+       __uint32_t      stale;                  /* count of stale lf entries */
+} xfs_dir2_block_tail_t;
+
+
+/* those are from xfs_dir2_sf.h */
+
+/*
+ * Directory layout when stored internal to an inode.
+ *
+ * Small directories are packed as tightly as possible so as to
+ * fit into the literal area of the inode.
+ */
+
+/*
+ * Inode number stored as 8 8-bit values.
+ */
+typedef        struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
+
+/*
+ * Inode number stored as 4 8-bit values.
+ * Works a lot of the time, when all the inode numbers in a directory
+ * fit in 32 bits.
+ */
+typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
+
+typedef union {
+       xfs_dir2_ino8_t i8;
+       xfs_dir2_ino4_t i4;
+} xfs_dir2_inou_t;
+
+/*
+ * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
+ * Only need 16 bits, this is the byte offset into the single block form.
+ */
+typedef struct { __uint8_t i[2]; } xfs_dir2_sf_off_t;
+
+/*
+ * The parent directory has a dedicated field, and the self-pointer must
+ * be calculated on the fly.
+ *
+ * Entries are packed toward the top as tightly as possible.  The header
+ * and the elements must be bcopy()'d out into a work area to get correct
+ * alignment for the inode number fields.
+ */
+typedef struct xfs_dir2_sf_hdr {
+       __uint8_t               count;          /* count of entries */
+       __uint8_t               i8count;        /* count of 8-byte inode #s */
+       xfs_dir2_inou_t         parent;         /* parent dir inode number */
+} xfs_dir2_sf_hdr_t;
+
+typedef struct xfs_dir2_sf_entry {
+       __uint8_t               namelen;        /* actual name length */
+       xfs_dir2_sf_off_t       offset;         /* saved offset */
+       __uint8_t               name[1];        /* name, variable size */
+       xfs_dir2_inou_t         inumber;        /* inode number, var. offset */
+} xfs_dir2_sf_entry_t;
+
+typedef struct xfs_dir2_sf {
+       xfs_dir2_sf_hdr_t       hdr;            /* shortform header */
+       xfs_dir2_sf_entry_t     list[1];        /* shortform entries */
+} xfs_dir2_sf_t;
+
+/* those are from xfs_dinode.h */
+
+#define        XFS_DINODE_VERSION_1    1
+#define        XFS_DINODE_VERSION_2    2
+#define        XFS_DINODE_MAGIC        0x494e  /* 'IN' */
+
+/*
+ * Disk inode structure.
+ * This is just the header; the inode is expanded to fill a variable size
+ * with the last field expanding.  It is split into the core and "other"
+ * because we only need the core part in the in-core inode.
+ */
+typedef struct xfs_timestamp {
+       __int32_t       t_sec;          /* timestamp seconds */
+       __int32_t       t_nsec;         /* timestamp nanoseconds */
+} xfs_timestamp_t;
+
+/*
+ * Note: Coordinate changes to this structure with the XFS_DI_* #defines
+ * below and the offsets table in xfs_ialloc_log_di().
+ */
+typedef struct xfs_dinode_core
+{
+       __uint16_t      di_magic;       /* inode magic # = XFS_DINODE_MAGIC */
+       __uint16_t      di_mode;        /* mode and type of file */
+       __int8_t        di_version;     /* inode version */
+       __int8_t        di_format;      /* format of di_c data */
+       __uint16_t      di_onlink;      /* old number of links to file */
+       __uint32_t      di_uid;         /* owner's user id */
+       __uint32_t      di_gid;         /* owner's group id */
+       __uint32_t      di_nlink;       /* number of links to file */
+       __uint16_t      di_projid;      /* owner's project id */
+       __uint8_t       di_pad[10];     /* unused, zeroed space */
+       xfs_timestamp_t di_atime;       /* time last accessed */
+       xfs_timestamp_t di_mtime;       /* time last modified */
+       xfs_timestamp_t di_ctime;       /* time created/inode modified */
+       xfs_fsize_t     di_size;        /* number of bytes in file */
+       xfs_drfsbno_t   di_nblocks;     /* # of direct & btree blocks used */
+       xfs_extlen_t    di_extsize;     /* basic/minimum extent size for file */
+       xfs_extnum_t    di_nextents;    /* number of extents in data fork */
+       xfs_aextnum_t   di_anextents;   /* number of extents in attribute fork*/
+       __uint8_t       di_forkoff;     /* attr fork offs, <<3 for 64b align */
+       __int8_t        di_aformat;     /* format of attr fork's data */
+       __uint32_t      di_dmevmask;    /* DMIG event mask */
+       __uint16_t      di_dmstate;     /* DMIG state info */
+       __uint16_t      di_flags;       /* random flags, XFS_DIFLAG_... */
+       __uint32_t      di_gen;         /* generation number */
+} xfs_dinode_core_t;
+
+typedef struct xfs_dinode
+{
+       xfs_dinode_core_t       di_core;
+       xfs_agino_t             di_next_unlinked;/* agi unlinked list ptr */
+       union {
+               xfs_bmdr_block_t di_bmbt;       /* btree root block */
+               xfs_bmbt_rec_32_t di_bmx[1];    /* extent list */
+               xfs_dir2_sf_t   di_dir2sf;      /* shortform directory v2 */
+               char            di_c[1];        /* local contents */
+       } di_u;
+} xfs_dinode_t;
+
+/*
+ * Values for di_format
+ */
+typedef enum xfs_dinode_fmt
+{
+       XFS_DINODE_FMT_DEV,             /* CHR, BLK: di_dev */
+       XFS_DINODE_FMT_LOCAL,           /* DIR, REG: di_c */
+                                       /* LNK: di_symlink */
+       XFS_DINODE_FMT_EXTENTS,         /* DIR, REG, LNK: di_bmx */
+       XFS_DINODE_FMT_BTREE,           /* DIR, REG, LNK: di_bmbt */
+       XFS_DINODE_FMT_UUID             /* MNT: di_uuid */
+} xfs_dinode_fmt_t;
+
+/*
+ * File types (mode field)
+ */
+#define        IFMT            0170000         /* type of file */
+#define        IFDIR           0040000         /* directory */
+#define        IFREG           0100000         /* regular */
+#define        IFLNK           0120000         /* symbolic link */
index d7a92775570522430c1f29bff4df10d574f92663..99d60b789bce73ff338b862b5be3fd3dd147e90d 100644 (file)
@@ -7,7 +7,6 @@ struct boot_param_t {
        struct boot_fspec_t     kernel;
        struct boot_fspec_t     rd;
        struct boot_fspec_t     sysmap;
-       struct boot_fspec_t     splash;
 
        char*   args;
 };
@@ -17,4 +16,4 @@ extern char bootdevice[];
 extern char *bootpath;
 extern int bootpartition;
 
-#endif
\ No newline at end of file
+#endif
index 45f1409e2218dd06f1743ae440df36c8cf31ca64..4e3b248f644d7c9cc6ba888b9dfe58d75273249c 100644 (file)
@@ -101,10 +101,10 @@ void release (void *ptr)
     malloc_ptr = (char *) ptr;
 }
 
-void *strdup(char *str)
+char *strdup(char const *str)
 {
     char *p = malloc(strlen(str) + 1);
-
-    strcpy(p, str);
+    if (p)
+        strcpy(p, str);
     return p;
 }
index ee90116cd9ceeab9cdc9d1b8c16af415c13a58f0..00414be021bbe285b90cb01a04eec91879f2d9da 100644 (file)
@@ -62,7 +62,6 @@ CONFIG cf_options[] =
     {cft_strg, "pause-message", NULL},
     {cft_strg, "init-code", NULL},
     {cft_strg, "init-message", NULL},
-    {cft_strg, "splash", NULL},
     {cft_strg, "fgcolor", NULL},
     {cft_strg, "bgcolor", NULL},
     {cft_end, NULL, NULL}};
@@ -88,7 +87,6 @@ CONFIG cf_image[] =
     {cft_flag, "pause-after", NULL},
     {cft_strg, "pause-message", NULL},
     {cft_flag, "novideo", NULL},
-    {cft_strg, "splash", NULL},
     {cft_strg, "sysmap", NULL},
     {cft_end, NULL, NULL}};
 
@@ -432,9 +430,7 @@ void cfg_print_images (void)
        if (alias)
            printlabel (alias, 0);
     }
-    prom_printf ("\n\nYou can also type in custom image locations, in the form\n"
-           "{prom_path;}partno/path_to_image or {prom_path;}{partno}[start-end]\n"
-           "Example: hd:3,/vmlinux\n\n");
+    prom_printf("\n");
 }
 
 char *cfg_get_default (void)
index 726f313b1de2672e66f3ecbad69fcfc4a7d844f9..3aaef8223b527b6b207b005e575ca05c5808e699 100644 (file)
@@ -25,6 +25,7 @@
 #include "string.h"
 #include "partition.h"
 #include "fs.h"
+#include "errors.h"
 
 extern char bootdevice[1024];
 
@@ -33,6 +34,60 @@ extern char bootdevice[1024];
    the string passed in parameters is changed since 0 are put in place
    of some separators to terminate the various strings
  */
+
+int
+parse_device_path(char *imagepath, char *defdevice, int defpart,
+                 char *deffile, struct boot_fspec_t *result)
+{
+     char *ptr;
+     char *ipath = strdup(imagepath);
+     char *defdev = strdup(defdevice);
+
+     result->dev = NULL;
+     result->part = -1;
+     result->file = NULL;
+
+     if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) {
+         if ((ptr = strchr(defdev, ':')) != NULL)
+              *ptr = 0; /* remove trailing : from defdevice if necessary */
+     }
+
+     if (!imagepath)
+         goto punt;
+
+     if ((ptr = strrchr(ipath, ',')) != NULL) {
+         result->file = strdup(ptr+1);
+         /* Trim the filename off */
+         *ptr = 0;
+     }
+
+     if (strstr(ipath, "ethernet") || strstr(ipath, "enet"))
+         result->dev = strdup(ipath);
+     else if ((ptr = strchr(ipath, ':')) != NULL) {
+         *ptr = 0;
+         result->dev = strdup(ipath);
+         if (*(ptr+1))
+              result->part = simple_strtol(ptr+1, NULL, 10);
+     } else if (strlen(ipath)) {
+          result->file = strdup(ipath);
+     } else {
+         return 0;
+     }
+     
+ punt:
+     if (!result->dev)
+         result->dev = strdup(defdev);
+     
+     if (result->part < 0)
+         result->part = defpart;
+     
+     if (!result->file)
+         result->file = strdup(deffile);
+     free(ipath);
+     return 1;
+}
+
+#if 0
 char *
 parse_device_path(char *of_device, char **file_spec, int *partition)
 {
@@ -43,30 +98,41 @@ parse_device_path(char *of_device, char **file_spec, int *partition)
        if (partition)
                *partition = -1;
 
+       DEBUG_F("of_device before parsing: %s\n", of_device);
        p = strchr(of_device, ':');
-       if (p)
-               *p = 0;
-       else
-               return of_device;
-       
-       last = ++p;
+       DEBUG_F("of_device after parsing: %s\n", p);
+
+       if (!p) {                          /* if null terminated we are finished */
+            DEBUG_F("of_device: %s\n", of_device);
+            return of_device;
+       }
+#if 0 /* this is broken crap, breaks netboot entirely */
+       else if (strstr(of_device, "ethernet") != NULL)
+            p = strchr(of_device, ',');  /* skip over ip all the way to the ',' */
+       else if (strstr(of_device, "enet") != NULL)
+            p = strchr(of_device, ',');  /* skip over ip all the way to the ',' */
+#endif
+       *p = 0;
+       last = ++p;                       /* sets to start of second part */
        while(*p && *p != ',') {
         if (!isdigit (*p)) {
-                       p = last;
-                       break;
-               }
-               ++p;
+            p = last;
+            break;
+       }
+       ++p;
        }
        if (p != last) {
-               *(p++) = 0;
-               if (partition)
-            *partition = simple_strtol(last, NULL, 10);
+            *(p++) = 0;
+            if (partition)
+                 *partition = simple_strtol(last, NULL, 10);
        }
        if (*p && file_spec)
-               *file_spec = p;
-               
-       return of_device;
+            *file_spec = p;
 
+       DEBUG_F("of_device: %s\n", of_device);
+       strcat(of_device, ":");
+       DEBUG_F("of_device after strcat: %s\n", of_device);
+       return of_device;
 }
 
 int
@@ -90,6 +156,8 @@ validate_fspec(              struct boot_fspec_t*    spec,
     return FILE_ERR_OK;
 }
 
+#endif
+
 static int
 file_block_open(       struct boot_file_t*     file,
                        const char*             dev_name,
@@ -110,10 +178,8 @@ file_block_open(   struct boot_file_t*     file,
                prom_printf("no partitions found.\n");
 #endif
        for (p = parts; p && !found; p=p->next) {
-#if DEBUG
-               prom_printf("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
+               DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
                        p->part_number, p->part_start, p->part_size );
-#endif
                if (partition == -1) {
                         file->fs = fs_open( file, dev_name, p, file_name );
                        if (file->fs != NULL)
@@ -130,14 +196,14 @@ file_block_open(  struct boot_file_t*     file,
        /* Note: we don't skip when found is NULL since we can, in some
         * cases, let OF figure out a default partition.
         */
-        DEBUG_F( "Using OF defaults.. (found = 0x%x)\n", found );
+        DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
         file->fs = fs_open( file, dev_name, found, file_name );
 
 bail:
        if (parts)
                partitions_free(parts);
 
-       return file->fs ? FILE_ERR_OK : FILE_ERR_NOTFOUND;
+       return fserrorno;
 }
 
 static int
@@ -186,10 +252,10 @@ static struct fs_t fs_default =
 int open_file( const struct boot_fspec_t*      spec,
                struct boot_file_t*             file)
 {
-       static char     temp[1024];
+//     static char     temp[1024];
        static char     temps[64];
-       char            *dev_name;
-       char            *file_name = NULL;
+//     char            *dev_name;
+//     char            *file_name = NULL;
        phandle         dev;
        int             result;
        int             partition;
@@ -201,6 +267,7 @@ int open_file(      const struct boot_fspec_t*      spec,
        /* First, see if a device was specified for the kernel
         * if not, we hope that the user wants a kernel on the same
         * drive and partition as yaboot itself */
+#if 0 /* this is crap */
        if (!spec->dev)
                strcpy(spec->dev, bootdevice);
        strncpy(temp,spec->dev,1024);
@@ -208,30 +275,30 @@ int open_file(    const struct boot_fspec_t*      spec,
        if (file_name == NULL)
                file_name = (char *)spec->file;
        if (file_name == NULL) {
-               prom_printf("booting without a file name not yet supported !\n");
-               return FILE_ERR_NOTFOUND;
+            prom_printf("Configuration error: null filename\n");
+            return FILE_ERR_NOTFOUND;
        }
        if (partition == -1)
+#endif
                partition = spec->part;
 
-#if DEBUG
-       prom_printf("dev_path = %s\nfile_name = %s\npartition = %d\n",
-               dev_name, file_name, partition);
-#endif 
+
+       DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
+               spec->dev, spec->file, partition);
+
        /* Find OF device phandle */
-       dev = prom_finddevice(dev_name);
+       dev = prom_finddevice(spec->dev);
        if (dev == PROM_INVALID_HANDLE) {
-               prom_printf("device not found !\n");
-               return FILE_ERR_NOTFOUND;
+               return FILE_ERR_BADDEV;
        }
-#if DEBUG
-       prom_printf("dev_phandle = %08lx\n", dev);
-#endif 
+
+       DEBUG_F("dev_phandle = %p\n", dev);
+
        /* Check the kind of device */
        result = prom_getprop(dev, "device_type", temps, 63);
        if (result == -1) {
                prom_printf("can't get <device_type> for device\n");
-               return FILE_ERR_NOTFOUND;
+               return FILE_ERR_BADDEV;
        }
        temps[result] = 0;
        if (!strcmp(temps, "block"))
@@ -240,20 +307,23 @@ int open_file(    const struct boot_fspec_t*      spec,
                file->device_kind = FILE_DEVICE_NET;
        else {
                prom_printf("Unkown device type <%s>\n", temps);
-               return FILE_ERR_NOTFOUND;
+               return FILE_ERR_BADDEV;
        }
        
        switch(file->device_kind) {
            case FILE_DEVICE_BLOCK:
-#if DEBUG
-               prom_printf("device is a block device\n");
-#endif
-               return file_block_open(file, dev_name, file_name, partition);
+               DEBUG_F("device is a block device\n");
+               return file_block_open(file, spec->dev, spec->file, partition);
            case FILE_DEVICE_NET:
-#if DEBUG
-               prom_printf("device is a network device\n");
-#endif
-               return file_net_open(file, dev_name, file_name);
+               DEBUG_F("device is a network device\n");
+               return file_net_open(file, spec->dev, spec->file);
        }
        return 0;
 }
+
+/* 
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
index b5ba2ca655925081307e9dec7debdba8b0824a32..1744f7de3f28951cafd3d9bddc8fa10e069fcf06 100644 (file)
 
 #include "stdlib.h"
 #include "fs.h"
+#include "errors.h"
 
 extern const struct fs_t       of_filesystem;
 extern const struct fs_t       of_net_filesystem;
 extern const struct fs_t       ext2_filesystem;
-extern const struct fs_t        reiserfs_filesystem;
 //extern const struct fs_t     iso_filesystem;
 
+/* Configurable filesystems */
+
+#ifdef CONFIG_FS_XFS
+extern const struct fs_t        xfs_filesystem;
+#endif /* CONFIG_FS_XFS */
+
+#ifdef CONFIG_FS_REISERFS
+extern const struct fs_t        reiserfs_filesystem;
+#endif /* CONFIG_FS_REISERFS */
+
 /* Filesystem handlers yaboot knows about */
 static const struct fs_t *block_filesystems[] = {
        &ext2_filesystem,               /* ext2 */
+#ifdef CONFIG_FS_XFS
+       &xfs_filesystem,                /* XFS */
+#endif /* CONFIG_FS_XFS */
+#ifdef CONFIG_FS_REISERFS
        &reiserfs_filesystem,           /* reiserfs */
+#endif /* CONFIG_FS_REISERFS */
        &of_filesystem,                 /* HFS/HFS+, ISO9660, UDF, UFS */
        NULL
 };
@@ -39,13 +54,13 @@ const struct fs_t *fs_of = &of_filesystem;              /* needed by ISO9660 */
 const struct fs_t *fs_of_netboot = &of_net_filesystem;  /* needed by file.c */
 
 const struct fs_t *
-fs_open( struct boot_file_t *file, const char *dev_name,
-         struct partition_t *part, const char *file_name)
+fs_open(struct boot_file_t *file, const char *dev_name,
+       struct partition_t *part, const char *file_name)
 {
-    const struct fs_t **fs;
-    for( fs = block_filesystems; *fs; fs++ )
-        if( (*fs)->open( file, dev_name, part, file_name ) == FILE_ERR_OK )
-            break;
+     const struct fs_t **fs;
+     for (fs = block_filesystems; *fs; fs++)
+         if ((fserrorno = (*fs)->open(file, dev_name, part, file_name)) != FILE_ERR_BAD_FSYS)
+              break;
 
-    return *fs;
+     return *fs;
 }
index e2a5070f7a4480416e1aae2238a89bdbf91e8f7b..af3d115acb171f9f9cdbb6a83bb427ae3736287b 100644 (file)
@@ -33,6 +33,7 @@
 #include "string.h"
 #include "partition.h"
 #include "fs.h"
+#include "errors.h"
 
 #define FAST_VERSION
 #define MAX_READ_RANGE 256
@@ -124,6 +125,7 @@ ext2_open(  struct boot_file_t*     file,
                const char*             file_name)
 {
        int result = 0;
+       int error = FILE_ERR_NOTFOUND;
        static char buffer[1024];
        int ofopened = 0;
        
@@ -132,11 +134,13 @@ ext2_open(        struct boot_file_t*     file,
 
        if (opened) {
                prom_printf("ext2_open() : fs busy\n");
-               return FILE_ERR_NOTFOUND;
+               DEBUG_LEAVE(FILE_ERR_FSBUSY);
+               return FILE_ERR_FSBUSY;
        }
        if (file->device_kind != FILE_DEVICE_BLOCK) {
                prom_printf("Can't open ext2 filesystem on non-block device\n");
-               return FILE_ERR_NOTFOUND;
+               DEBUG_LEAVE(FILE_ERR_BADDEV);
+               return FILE_ERR_BADDEV;
        }
 
        fs = NULL;
@@ -152,7 +156,7 @@ ext2_open(  struct boot_file_t*     file,
        cur_file = file;
 
 
-       DEBUG_F("partition offset: %d\n", doff);
+       DEBUG_F("partition offset: %Lu\n", doff);
 
        /* Open the OF device for the entire disk */
        strncpy(buffer, dev_name, 1020);
@@ -162,13 +166,13 @@ ext2_open(        struct boot_file_t*     file,
 
        file->of_device = prom_open(buffer);
 
-       DEBUG_F("file->of_device = %08lx\n", file->of_device);
+       DEBUG_F("file->of_device = %p\n", file->of_device);
 
        if (file->of_device == PROM_INVALID_HANDLE) {
 
-               DEBUG_F("Can't open device %s\n", file->of_device);
-
-               return FILE_ERR_NOTFOUND;
+               DEBUG_F("Can't open device %p\n", file->of_device);
+               DEBUG_LEAVE(FILE_IOERR);
+               return FILE_IOERR;
        }
        ofopened = 1;
        
@@ -178,7 +182,7 @@ ext2_open(  struct boot_file_t*     file,
 
             if(result == EXT2_ET_BAD_MAGIC)
             {
-                DEBUG_F( "ext2fs_open returned bad magic loading file %s\n",
+                DEBUG_F( "ext2fs_open returned bad magic loading file %p\n",
                          file );
             }
             else
@@ -186,7 +190,7 @@ ext2_open(  struct boot_file_t*     file,
                 DEBUG_F( "ext2fs_open error #%d while loading file %s\n",
                          result, file_name);
             }
-
+           error = FILE_ERR_BAD_FSYS;
            goto bail;
        }
 
@@ -195,7 +199,7 @@ ext2_open(  struct boot_file_t*     file,
        if (!block_buffer) {
 
            DEBUG_F("ext2fs: can't alloc block buffer (%d bytes)\n", fs->blocksize * 2);
-
+           error = FILE_IOERR;
            goto bail;
        }
        
@@ -205,6 +209,12 @@ ext2_open( struct boot_file_t*     file,
        if (result) {
 
            DEBUG_F("ext2fs_namei error #%d while loading file %s\n", result, file_name);
+           if (result == EXT2_ET_SYMLINK_LOOP)
+                error = FILE_ERR_SYMLINK_LOOP;
+           else if (result == EXT2_ET_FILE_NOT_FOUND)
+                error = FILE_ERR_NOTFOUND;
+           else
+                error = FILE_IOERR;
            goto bail;
        }
 
@@ -213,7 +223,7 @@ ext2_open(  struct boot_file_t*     file,
        if (result) {
 
            DEBUG_F("ext2fs_follow_link error #%d while loading file %s\n", result, file_name);
-
+           error = FILE_ERR_NOTFOUND;
            goto bail;
        }
 #endif 
@@ -223,7 +233,14 @@ ext2_open( struct boot_file_t*     file,
        if (result) {
 
            DEBUG_F("ext2fs_read_inode error #%d while loading file %s\n", result, file_name);
-
+           if (result == EXT2_ET_FILE_TOO_BIG)
+                error = FILE_ERR_LENGTH;
+           else if (result == EXT2_ET_LLSEEK_FAILED)
+                error = FILE_CANT_SEEK;
+           else if (result ==  EXT2_ET_FILE_NOT_FOUND)
+                error = FILE_ERR_NOTFOUND;
+           else
+                error = FILE_IOERR;
            goto bail;
        }
 #endif /* FAST_VERSION */
@@ -242,8 +259,8 @@ bail:
            block_buffer = NULL;
            cur_file = NULL;
            
-            DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-           return FILE_ERR_NOTFOUND;
+            DEBUG_LEAVE_F(error);
+           return error;
        }
 
        DEBUG_LEAVE(FILE_ERR_OK);
@@ -420,10 +437,10 @@ ext2_read(        struct boot_file_t*     file,
 
 #ifdef FAST_VERSION
        if (!opened)
-           return FILE_ERR_NOTFOUND;
+           return FILE_IOERR;
 
 
-       DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
+       DEBUG_F("ext_read() from pos 0x%Lx, size: 0x%ux\n", file->pos, size);
 
 
        read_cur_file = file;
@@ -447,7 +464,7 @@ ext2_read(  struct boot_file_t*     file,
                retval = read_result;
        }
        if (retval)
-               prom_printf ("ext2: i/o error %d in read\n", retval);
+               prom_printf ("ext2: i/o error %ld in read\n", (long) retval);
                
        return read_total;
 
@@ -456,7 +473,7 @@ ext2_read(  struct boot_file_t*     file,
        unsigned int read = 0;
        
        if (!opened)
-           return FILE_ERR_NOTFOUND;
+           return FILE_IOERR;
 
 
        DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
@@ -507,7 +524,7 @@ ext2_seek(  struct boot_file_t*     file,
                unsigned int            newpos)
 {
        if (!opened)
-               return FILE_ERR_NOTFOUND;
+               return FILE_CANT_SEEK;
 
        file->pos = newpos;
        return FILE_ERR_OK;
@@ -517,7 +534,7 @@ static int
 ext2_close(    struct boot_file_t*     file)
 {
        if (!opened)
-               return FILE_ERR_NOTFOUND;
+               return FILE_IOERR;
 
        if (block_buffer)
                free(block_buffer);
@@ -528,6 +545,7 @@ ext2_close( struct boot_file_t*     file)
        fs = NULL;
        
        prom_close(file->of_device);
+       DEBUG_F("ext2_close called\n");
 
        opened = 0;
            
@@ -586,7 +604,7 @@ static errcode_t linux_read_blk (io_channel channel, unsigned long block, int co
     size = (count < 0) ? -count : count * bs;
     prom_lseek(cur_file->of_device, tempb);
     if (prom_read(cur_file->of_device, data, size) != size) {
-       prom_printf ("\nRead error on block %d", block);
+       DEBUG_F("\nRead error on block %ld\n", block);
        return EXT2_ET_SHORT_READ;
     }
     return 0;
@@ -601,4 +619,3 @@ static errcode_t linux_flush (io_channel channel)
 {
     return 0;
 }
-
index 9f52a3da5fd103541e928cc04102b84990e91015..50479a9a1249e041933f2be027241752d326d3cd 100644 (file)
@@ -24,7 +24,7 @@
 #include "string.h"
 #include "partition.h"
 #include "fs.h"
-
+#include "errors.h"
 
 static int iso_open(   struct boot_file_t*     file,
                        const char*             dev_name,
@@ -52,7 +52,7 @@ iso_open(     struct boot_file_t*     file,
                struct partition_t*     part,
                const char*             file_name)
 {
-       return FILE_ERR_NOTFOUND;
+       return FILE_ERR_BAD_FSYS;
 }
 
 static int
@@ -60,14 +60,14 @@ iso_read(   struct boot_file_t*     file,
                unsigned int            size,
                void*                   buffer)
 {
-       return FILE_ERR_NOTFOUND;
+       return FILE_ERR_BAD_FSYS;
 }
 
 static int
 iso_seek(      struct boot_file_t*     file,
                unsigned int            newpos)
 {
-       return FILE_ERR_NOTFOUND;
+       return FILE_ERR_BAD_FSYS;
 }
 
 static int
index abb006b0a7394d83a0a02eaa78962eadf5174f7e..2dbc33389169f3387218b9e3e7ddbf0d942eeb65 100644 (file)
 #include "string.h"
 #include "partition.h"
 #include "fs.h"
-
+#include "errors.h"
 
 #define LOAD_BUFFER_POS                0x600000
 #define LOAD_BUFFER_SIZE       0x400000
 
-static int of_open(    struct boot_file_t*     file,
-                       const char*             dev_name,
-                       struct partition_t*     part,
-                       const char*             file_name);
-static int of_read(    struct boot_file_t*     file,
-                       unsigned int            size,
-                       void*                   buffer);
-static int of_seek(    struct boot_file_t*     file,
-                       unsigned int            newpos);
-static int of_close(   struct boot_file_t*     file);
-
-
-static int of_net_open(                struct boot_file_t*     file,
-                               const char*             dev_name,
-                               struct partition_t*     part,
-                               const char*             file_name);
-static int of_net_read(                struct boot_file_t*     file,
-                               unsigned int            size,
-                               void*                   buffer);
-static int of_net_seek(                struct boot_file_t*     file,
-                               unsigned int            newpos);
+static int of_open(struct boot_file_t* file, const char* dev_name,
+                  struct partition_t* part, const char* file_name);
+static int of_read(struct boot_file_t* file, unsigned int size, void* buffer);
+static int of_seek(struct boot_file_t* file, unsigned int newpos);
+static int of_close(struct boot_file_t* file);
+
+
+static int of_net_open(struct boot_file_t* file, const char* dev_name,
+                      struct partition_t* part, const char* file_name);
+static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer);
+static int of_net_seek(struct boot_file_t* file, unsigned int newpos);
 
 
 struct fs_t of_filesystem =
 {
-    "built-in",
-    of_open,
-    of_read,
-    of_seek,
-    of_close
+     "built-in",
+     of_open,
+     of_read,
+     of_seek,
+     of_close
 };
 
 struct fs_t of_net_filesystem =
 {
-    "built-in network",
-    of_net_open,
-    of_net_read,
-    of_net_seek,
-    of_close
+     "built-in network",
+     of_net_open,
+     of_net_read,
+     of_net_seek,
+     of_close
 };
 
-
-
 static int
-of_open(       struct boot_file_t*     file,
-               const char*             dev_name,
-               struct partition_t*     part,
-               const char*             file_name)
+of_open(struct boot_file_t* file, const char* dev_name,
+       struct partition_t* part, const char* file_name)
 {
-       static char     buffer[1024];
+     static char       buffer[1024];
+     char               *filename;
+     char               *p;
        
-        DEBUG_ENTER;
-        DEBUG_OPEN;
-
-       strncpy(buffer, dev_name, 1000);
-       strcat(buffer, ":");
-       if (part) {
-               char pn[3];
-               sprintf(pn, "%02d", part->part_number);
-               strcat(buffer, pn);
-       }
-       if (file_name && strlen(file_name)) {
-               if (part)
-                       strcat(buffer, ",");
-               strcat(buffer, file_name);
-       }
-                       
-       DEBUG_F("<%s>\n", buffer);
-
-       file->of_device = prom_open(buffer);
-
-       DEBUG_F("file->of_device = %08lx\n", file->of_device);
-
-       file->pos = 0;
-       file->buffer = NULL;
-       if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
-        {
-               DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-               return FILE_ERR_NOTFOUND;
-        }
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     strncpy(buffer, dev_name, 768);
+     strcat(buffer, ":");
+     if (part) {
+         char pn[3];
+         sprintf(pn, "%02d", part->part_number);
+         strcat(buffer, pn);
+     }
+     if (file_name && strlen(file_name)) {
+         if (part)
+              strcat(buffer, ",");
+         filename = strdup(file_name);
+         for (p = filename; *p; p++)
+              if (*p == '/') 
+                   *p = '\\';
+         strcat(buffer, filename);
+         free(filename);
+     }
+
+     DEBUG_F("opening: \"%s\"\n", buffer);
+
+     file->of_device = prom_open(buffer);
+
+     DEBUG_F("file->of_device = %p\n", file->of_device);
+
+     file->pos = 0;
+     file->buffer = NULL;
+     if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
+     {
+         DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+         return FILE_ERR_BAD_FSYS;
+     }
        
-       DEBUG_LEAVE(FILE_ERR_OK);
-       return FILE_ERR_OK;
+     DEBUG_LEAVE(FILE_ERR_OK);
+     return FILE_ERR_OK;
 }
 
 static int
-of_net_open(   struct boot_file_t*     file,
-               const char*             dev_name,
-               struct partition_t*     part,
-               const char*             file_name)
+of_net_open(struct boot_file_t* file, const char* dev_name,
+           struct partition_t* part, const char* file_name)
 {
-       static char     buffer[1024];
-       
-        DEBUG_ENTER;
-        DEBUG_OPEN;
-
-       strncpy(buffer, dev_name, 1000);
-       strcat(buffer, ":0");
-       if (file_name && strlen(file_name)) {
-               strcat(buffer, ",");
-               strcat(buffer, file_name);
-       }
+     static char       buffer[1024];
+     char               *filename;
+     char               *p;
+
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     strncpy(buffer, dev_name, 768);
+     if (file_name && strlen(file_name)) {
+         strcat(buffer, ",");
+         filename = strdup(file_name);
+         for (p = filename; *p; p++)
+              if (*p == '/') 
+                   *p = '\\';
+         strcat(buffer, filename);
+         free(filename);
+     }
                        
-       DEBUG_F("<%s>\n", buffer);
+     DEBUG_F("Opening: \"%s\"\n", buffer);
 
-       file->of_device = prom_open(buffer);
+     file->of_device = prom_open(buffer);
 
-       DEBUG_F("file->of_device = %08lx\n", file->of_device);
+     DEBUG_F("file->of_device = %p\n", file->of_device);
 
-       file->pos = 0;
-       if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
-        {
-                DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-               return FILE_ERR_NOTFOUND;
-        }
+     file->pos = 0;
+     if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
+     {
+         DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+         return FILE_ERR_BAD_FSYS;
+     }
        
-       file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0);
-       if (file->buffer == (void *)-1) {
-               prom_printf("Can't claim memory for TFTP download\n");
-               prom_close(file->of_device);
-               DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-               return FILE_ERR_NOTFOUND;
-       }
-       memset(file->buffer, 0, LOAD_BUFFER_SIZE);
-
-       DEBUG_F("TFP...\n");
-
-       file->len = prom_loadmethod(file->of_device, file->buffer);
+     file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0);
+     if (file->buffer == (void *)-1) {
+         prom_printf("Can't claim memory for TFTP download\n");
+         prom_close(file->of_device);
+         DEBUG_LEAVE(FILE_IOERR);
+         return FILE_IOERR;
+     }
+     memset(file->buffer, 0, LOAD_BUFFER_SIZE);
+
+     DEBUG_F("TFP...\n");
+
+     file->len = prom_loadmethod(file->of_device, file->buffer);
        
-       DEBUG_F("result: %d\n", file->len);
-
+     DEBUG_F("result: %Ld\n", file->len);
        
-        DEBUG_LEAVE(FILE_ERR_OK);
-       return FILE_ERR_OK;
+     DEBUG_LEAVE(FILE_ERR_OK);
+     return FILE_ERR_OK;
 }
 
 static int
-of_read(       struct boot_file_t*     file,
-               unsigned int            size,
-               void*                   buffer)
+of_read(struct boot_file_t* file, unsigned int size, void* buffer)
 {
-       unsigned int count;
+     unsigned int count;
        
-       count = prom_read(file->of_device, buffer, size);
-       file->pos += count;
-       return count;
+     count = prom_read(file->of_device, buffer, size);
+     file->pos += count;
+     return count;
 }
 
 static int
-of_net_read(   struct boot_file_t*     file,
-               unsigned int            size,
-               void*                   buffer)
+of_net_read(struct boot_file_t* file, unsigned int size, void* buffer)
 {
-       unsigned int count, av;
+     unsigned int count, av;
        
-       av = file->len - file->pos;
-       count = size > av ? av : size; 
-       memcpy(buffer, file->buffer + file->pos, count);
-       file->pos += count;
-       return count;
+     av = file->len - file->pos;
+     count = size > av ? av : size; 
+     memcpy(buffer, file->buffer + file->pos, count);
+     file->pos += count;
+     return count;
 }
 
 static int
-of_seek(       struct boot_file_t*     file,
-               unsigned int            newpos)
+of_seek(struct boot_file_t* file, unsigned int newpos)
 {
-       if (prom_seek(file->of_device, newpos)) {
-               file->pos = newpos;
-               return FILE_ERR_OK;
-       }
+     if (prom_seek(file->of_device, newpos)) {
+         file->pos = newpos;
+         return FILE_ERR_OK;
+     }
                
-       return FILE_CANT_SEEK;
+     return FILE_CANT_SEEK;
 }
 
 static int
-of_net_seek(   struct boot_file_t*     file,
-               unsigned int            newpos)
+of_net_seek(struct boot_file_t* file, unsigned int newpos)
 {
-       file->pos = (newpos > file->len) ? file->len : newpos;
-       return FILE_ERR_OK;
+     file->pos = (newpos > file->len) ? file->len : newpos;
+     return FILE_ERR_OK;
 }
 
 static int
-of_close(      struct boot_file_t*     file)
+of_close(struct boot_file_t* file)
 {
 
-        DEBUG_ENTER;
-       DEBUG_F("<@0x%08lx>n", file->of_device);
+     DEBUG_ENTER;
+     DEBUG_F("<@%p>\n", file->of_device);
 
-       if (file->buffer) {
-               prom_release(file->buffer, LOAD_BUFFER_SIZE);
-       }
-       prom_close(file->of_device);
+     if (file->buffer) {
+         prom_release(file->buffer, LOAD_BUFFER_SIZE);
+     }
+     prom_close(file->of_device);
+     DEBUG_F("of_close called\n");
 
-        DEBUG_LEAVE(0);
-       
-       return 0;
+     DEBUG_LEAVE(0);   
+     return 0;
 }
 
+/* 
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
index f28680fb69514a3bc9636263f7bd60cb8685559a..28f6d4e8778d6521c5d8970d2a4c48ab1b2626ea 100644 (file)
 #include "string.h"
 #include "stdlib.h"
 #include "fs.h"
+#include "errors.h"
 #include "reiserfs/reiserfs.h"
 
 
 /* Exported in struct fs_t */
 static int reiserfs_open( struct boot_file_t *file, const char *dev_name,
-    struct partition_t *part, const char *file_name );
+                         struct partition_t *part, const char *file_name );
 static int reiserfs_read( struct boot_file_t *file, unsigned int size,
 
-    void *buffer );
+                         void *buffer );
 static int reiserfs_seek( struct boot_file_t *file, unsigned int newpos );
 static int reiserfs_close( struct boot_file_t *file );
 
 struct fs_t reiserfs_filesystem = {
-    name:"reiserfs",
-    open:reiserfs_open,
-    read:reiserfs_read,
-    seek:reiserfs_seek,
-    close:reiserfs_close
+     name:"reiserfs",
+     open:reiserfs_open,
+     read:reiserfs_read,
+     seek:reiserfs_seek,
+     close:reiserfs_close
 };
 
 static int reiserfs_read_super( void );
@@ -63,123 +64,128 @@ static int
 reiserfs_open( struct boot_file_t *file, const char *dev_name,
                struct partition_t *part, const char *file_name )
 {
-    static char buffer[1024];
-
-    DEBUG_ENTER;
-    DEBUG_OPEN;
-
-    memset( INFO, 0, sizeof(struct reiserfs_state) );
-    INFO->file = file;
-
-    if (part)
-    {
-        DEBUG_F( "Determining offset for partition %d\n", part->part_number );
-        INFO->partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
-        DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
-                                     part->part_start,
-                                     part->blocksize );
-    }
-    else
-        INFO->partition_offset = 0;
-
-    sprintf( buffer, "%s:%d", dev_name, /*part ? part->part_number :*/ 0 );
-    file->of_device = prom_open( buffer );
-    DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
-             buffer, file_name, INFO->partition_offset );
-
-    if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL )
-    {
-       DEBUG_F( "Can't open device %s\n", file->of_device );
-        DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-       return FILE_ERR_NOTFOUND;
-    }
-
-    DEBUG_F( "%s was successfully opened\n" );
-
-    if ( reiserfs_read_super() != 1 )
-    {
-       DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset );
-       prom_close( file->of_device );
-        DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-       return FILE_ERR_NOTFOUND;
-    }
-
-    DEBUG_F( "Attempting to open %s\n", file_name );
-    strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */
-    if( reiserfs_open_file(buffer) == 0 )
-    {
-        DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum );
-        prom_close( file->of_device );
-        DEBUG_LEAVE(FILE_ERR_NOTFOUND);
-        return FILE_ERR_NOTFOUND;
-    }
-
-    DEBUG_F( "Successfully opened %s\n", file_name );
-
-    DEBUG_LEAVE(FILE_ERR_OK);
-    return FILE_ERR_OK;
+     static char buffer[1024];
+
+     DEBUG_ENTER;
+     DEBUG_OPEN;
+
+     memset( INFO, 0, sizeof(struct reiserfs_state) );
+     INFO->file = file;
+
+     if (part)
+     {
+         DEBUG_F( "Determining offset for partition %d\n", part->part_number );
+         INFO->partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
+         DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
+                  part->part_start,
+                  part->blocksize );
+     }
+     else
+         INFO->partition_offset = 0;
+
+     sprintf( buffer, "%s:%d", dev_name, 0 ); /* 0 is full disk in OF */
+     file->of_device = prom_open( buffer );
+     DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
+             buffer, file_name, INFO->partition_offset );
+
+     if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL )
+     {
+         DEBUG_F( "Can't open device %p\n", file->of_device );
+         DEBUG_LEAVE(FILE_ERR_BADDEV);
+         return FILE_ERR_BADDEV;
+     }
+
+     DEBUG_F("%p was successfully opened\n", file->of_device);
+
+     if ( reiserfs_read_super() != 1 )
+     {
+         DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset );
+         prom_close( file->of_device );
+         DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+         return FILE_ERR_BAD_FSYS;
+     }
+
+     DEBUG_F( "Attempting to open %s\n", file_name );
+     strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */
+     if (reiserfs_open_file(buffer) == 0)
+     {
+         DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum );
+         prom_close( file->of_device );
+         DEBUG_LEAVE_F(errnum);
+         return errnum;
+     }
+
+     DEBUG_F( "Successfully opened %s\n", file_name );
+
+     DEBUG_LEAVE(FILE_ERR_OK);
+     DEBUG_SLEEP;
+     return FILE_ERR_OK;
 }
 
 static int
 reiserfs_read( struct boot_file_t *file, unsigned int size, void *buffer )
 {
-    return reiserfs_read_data( buffer, size );
+     return reiserfs_read_data( buffer, size );
 }
 
 static int
 reiserfs_seek( struct boot_file_t *file, unsigned int newpos )
 {
-    file->pos = newpos;
-    return FILE_ERR_OK;
+     file->pos = newpos;
+     return FILE_ERR_OK;
 }
 
 static int
 reiserfs_close( struct boot_file_t *file )
 {
-    if( file->of_device )
-    {
-        prom_close(file->of_device);
-        file->of_device = 0;
-    }
-    return FILE_ERR_OK;
+     if( file->of_device )
+     {
+         prom_close(file->of_device);
+         file->of_device = 0;
+         DEBUG_F("reiserfs_close called\n");
+     }
+     return FILE_ERR_OK;
 }
 
 
 static __inline__ __u32
 log2( __u32 word )
 {
-    int i = 0;
-    while( word && (word & (1 << ++i)) == 0 );
-    return i;
+     int i = 0;
+     while( word && (word & (1 << ++i)) == 0 );
+     return i;
 }
 
 static __inline__ int
 is_power_of_two( unsigned long word )
 {
-    return ( word & -word ) == word;
+     return ( word & -word ) == word;
 }
 
 static int
 read_disk_block( struct boot_file_t *file, __u32 block, __u32 start,
                  __u32 length, void *buf )
 {
-    __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
-                                              : INFO->blocksize;
-    unsigned long long pos = block * fs_blocksize;
-    pos += INFO->partition_offset + start;
-    DEBUG_F( "Reading %lu bytes, starting at block %lu, disk offset %Lu\n",
-             length, block, pos );
-    prom_lseek( file->of_device, pos );
-    return prom_read( file->of_device, buf, length );
+     __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
+         : INFO->blocksize;
+     unsigned long long pos = block * fs_blocksize;
+     pos += INFO->partition_offset + start;
+     DEBUG_F( "Reading %u bytes, starting at block %u, disk offset %Lu\n",
+             length, block, pos );
+     if (!prom_lseek( file->of_device, pos )) {
+         DEBUG_F("prom_lseek failed\n");
+         return 0;
+     }
+     return prom_read( file->of_device, buf, length );
 }
 
 
 static int
 journal_read( __u32 block, __u32 len, char *buffer )
 {
-    return read_disk_block( INFO->file,
-                      (INFO->journal_block + block), 0,
-                       len, buffer );
+     return read_disk_block( INFO->file,
+                            (INFO->journal_block + block), 0,
+                            len, buffer );
 }
 
 /* Read a block from ReiserFS file system, taking the journal into
@@ -189,76 +195,76 @@ journal_read( __u32 block, __u32 len, char *buffer )
 static int
 block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
 {
-    __u32 transactions = INFO->journal_transactions;
-    __u32 desc_block = INFO->journal_first_desc;
-    __u32 journal_mask = INFO->journal_block_count - 1;
-    __u32 translatedNr = blockNr;
-    __u32 *journal_table = JOURNAL_START;
+     __u32 transactions = INFO->journal_transactions;
+     __u32 desc_block = INFO->journal_first_desc;
+     __u32 journal_mask = INFO->journal_block_count - 1;
+     __u32 translatedNr = blockNr;
+     __u32 *journal_table = JOURNAL_START;
 
 //    DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len );
 
-    while ( transactions-- > 0 )
-    {
-       int i = 0;
-       int j_len;
-
-       if ( *journal_table != 0xffffffff )
-       {
-           /* Search for the blockNr in cached journal */
-           j_len = le32_to_cpu(*journal_table++);
-           while ( i++ < j_len )
-           {
-               if ( le32_to_cpu(*journal_table++) == blockNr )
-               {
-                   journal_table += j_len - i;
-                   goto found;
-               }
-           }
-       }
-       else
-       {
-           /* This is the end of cached journal marker.  The remaining
-            * transactions are still on disk. */
-           struct reiserfs_journal_desc desc;
-           struct reiserfs_journal_commit commit;
-
-           if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
-               return 0;
-
-           j_len = le32_to_cpu(desc.j_len);
-           while ( i < j_len && i < JOURNAL_TRANS_HALF )
-               if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
-                   goto found;
+     while ( transactions-- > 0 )
+     {
+         int i = 0;
+         int j_len;
+
+         if ( *journal_table != 0xffffffff )
+         {
+              /* Search for the blockNr in cached journal */
+              j_len = le32_to_cpu(*journal_table++);
+              while ( i++ < j_len )
+              {
+                   if ( le32_to_cpu(*journal_table++) == blockNr )
+                   {
+                        journal_table += j_len - i;
+                        goto found;
+                   }
+              }
+         }
+         else
+         {
+              /* This is the end of cached journal marker.  The remaining
+               * transactions are still on disk. */
+              struct reiserfs_journal_desc desc;
+              struct reiserfs_journal_commit commit;
+
+              if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
+                   return 0;
 
-           if ( j_len >= JOURNAL_TRANS_HALF )
-           {
-               int commit_block = ( desc_block + 1 + j_len ) & journal_mask;
+              j_len = le32_to_cpu(desc.j_len);
+              while ( i < j_len && i < JOURNAL_TRANS_HALF )
+                   if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
+                        goto found;
 
-               if ( !journal_read( commit_block,
-                       sizeof(commit), (char *) &commit ) )
-                   return 0;
+              if ( j_len >= JOURNAL_TRANS_HALF )
+              {
+                   int commit_block = ( desc_block + 1 + j_len ) & journal_mask;
+
+                   if ( !journal_read( commit_block,
+                                       sizeof(commit), (char *) &commit ) )
+                        return 0;
 
-               while ( i < j_len )
-                   if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
-                       goto found;
-           }
-       }
-       goto not_found;
+                   while ( i < j_len )
+                        if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
+                             goto found;
+              }
+         }
+         goto not_found;
 
-      found:
-       translatedNr =
-           INFO->journal_block + ( ( desc_block + i ) & journal_mask );
+     found:
+         translatedNr =
+              INFO->journal_block + ( ( desc_block + i ) & journal_mask );
 
-       DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
-           blockNr, translatedNr - INFO->journal_block );
+         DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
+                  blockNr, translatedNr - INFO->journal_block );
 
-       /* We must continue the search, as this block may be overwritten in 
-        * later transactions. */
-      not_found:
-       desc_block = (desc_block + 2 + j_len) & journal_mask;
-    }
+         /* We must continue the search, as this block may be overwritten in 
+          * later transactions. */
+     not_found:
+         desc_block = (desc_block + 2 + j_len) & journal_mask;
+     }
 
-    return read_disk_block( INFO->file, translatedNr, start, len, buffer );
+     return read_disk_block( INFO->file, translatedNr, start, len, buffer );
 }
 
 /* Init the journal data structure.  We try to cache as much as
@@ -272,215 +278,222 @@ block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
 static int
 journal_init( void )
 {
-    struct reiserfs_journal_header header;
-    struct reiserfs_journal_desc desc;
-    struct reiserfs_journal_commit commit;
-    __u32 block_count = INFO->journal_block_count;
-    __u32 desc_block;
-    __u32 commit_block;
-    __u32 next_trans_id;
-    __u32 *journal_table = JOURNAL_START;
-
-    journal_read( block_count, sizeof ( header ), ( char * ) &header );
-    desc_block = le32_to_cpu(header.j_first_unflushed_offset);
-    if ( desc_block >= block_count )
-       return 0;
-
-    INFO->journal_transactions = 0;
-    INFO->journal_first_desc = desc_block;
-    next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1;
-
-    DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) );
-
-    while ( 1 )
-    {
-       journal_read( desc_block, sizeof(desc), (char *) &desc );
-       if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0
-           || desc.j_trans_id != next_trans_id
-           || desc.j_mount_id != header.j_mount_id )
-           /* no more valid transactions */
-           break;
-
-       commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 );
-       journal_read( commit_block, sizeof(commit), (char *) &commit );
-       if ( desc.j_trans_id != commit.j_trans_id
-           || desc.j_len != commit.j_len )
-           /* no more valid transactions */
-           break;
-
-
-       DEBUG_F( "Found valid transaction %u/%u at %u.\n",
-           le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
-            desc_block );
-
-
-       next_trans_id++;
-       if ( journal_table < JOURNAL_END )
-       {
-           if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END )
-           {
-               /* The table is almost full; mark the end of the cached * *
-                * journal. */
-               *journal_table = 0xffffffff;
-               journal_table = JOURNAL_END;
-           }
-           else
-           {
-               int i;
-
-               /* Cache the length and the realblock numbers in the table. * 
-                * The block number of descriptor can easily be computed. *
-                * and need not to be stored here. */
-               *journal_table++ = desc.j_len;
-               for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ )
-               {
-                   *journal_table++ = desc.j_realblock[i];
-
-                   DEBUG_F( "block %u is in journal %u.\n",
-                       le32_to_cpu(desc.j_realblock[i]), desc_block );
-
-               }
-               for ( ; i < le32_to_cpu(desc.j_len); i++ )
-               {
-                   *journal_table++ =
-                       commit.j_realblock[i - JOURNAL_TRANS_HALF];
-
-                   DEBUG_F( "block %u is in journal %u.\n",
-                       le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]),
-                       desc_block );
-
-               }
-           }
-       }
-       desc_block = (commit_block + 1) & (block_count - 1);
-    }
-
-    DEBUG_F( "Transaction %u/%u at %u isn't valid.\n",
-       le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
-        desc_block );
-
-
-    INFO->journal_transactions
-       = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1;
-    return errnum == 0;
+     struct reiserfs_journal_header header;
+     struct reiserfs_journal_desc desc;
+     struct reiserfs_journal_commit commit;
+     __u32 block_count = INFO->journal_block_count;
+     __u32 desc_block;
+     __u32 commit_block;
+     __u32 next_trans_id;
+     __u32 *journal_table = JOURNAL_START;
+
+     journal_read( block_count, sizeof ( header ), ( char * ) &header );
+     desc_block = le32_to_cpu(header.j_first_unflushed_offset);
+     if ( desc_block >= block_count )
+         return 0;
+
+     INFO->journal_transactions = 0;
+     INFO->journal_first_desc = desc_block;
+     next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1;
+
+     DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) );
+
+     while ( 1 )
+     {
+         journal_read( desc_block, sizeof(desc), (char *) &desc );
+         if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0
+              || desc.j_trans_id != next_trans_id
+              || desc.j_mount_id != header.j_mount_id )
+              /* no more valid transactions */
+              break;
+
+         commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 );
+         journal_read( commit_block, sizeof(commit), (char *) &commit );
+         if ( desc.j_trans_id != commit.j_trans_id
+              || desc.j_len != commit.j_len )
+              /* no more valid transactions */
+              break;
+
+
+         DEBUG_F( "Found valid transaction %u/%u at %u.\n",
+                  le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+                  desc_block );
+
+
+         next_trans_id++;
+         if ( journal_table < JOURNAL_END )
+         {
+              if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END )
+              {
+                   /* The table is almost full; mark the end of the cached * *
+                    * journal. */
+                   *journal_table = 0xffffffff;
+                   journal_table = JOURNAL_END;
+              }
+              else
+              {
+                   int i;
+
+                   /* Cache the length and the realblock numbers in the table. * 
+                    * The block number of descriptor can easily be computed. *
+                    * and need not to be stored here. */
+                   *journal_table++ = desc.j_len;
+                   for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ )
+                   {
+                        *journal_table++ = desc.j_realblock[i];
+
+                        DEBUG_F( "block %u is in journal %u.\n",
+                                 le32_to_cpu(desc.j_realblock[i]), desc_block );
+
+                   }
+                   for ( ; i < le32_to_cpu(desc.j_len); i++ )
+                   {
+                        *journal_table++ =
+                             commit.j_realblock[i - JOURNAL_TRANS_HALF];
+
+                        DEBUG_F( "block %u is in journal %u.\n",
+                                 le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]),
+                                 desc_block );
+
+                   }
+              }
+         }
+         desc_block = (commit_block + 1) & (block_count - 1);
+     }
+
+     DEBUG_F( "Transaction %u/%u at %u isn't valid.\n",
+             le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+             desc_block );
+
+
+     INFO->journal_transactions
+         = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1;
+     return (errnum == 0);
 }
 
 /* check filesystem types and read superblock into memory buffer */
 static int
 reiserfs_read_super( void )
 {
-    struct reiserfs_super_block super;
-    __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;
-
-    read_disk_block( INFO->file, superblock, 0, sizeof(super), &super );
-
-    DEBUG_F( "Found super->magic %s\n", super.s_magic );
-
-    if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
-        strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
-    {
-       /* Try old super block position */
-       superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;
-       read_disk_block( INFO->file, superblock, 0, sizeof (super),  &super );
-
-       if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
-             strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
-       {
-           /* pre journaling super block - untested */
-           if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
-                    (char *) ((__u32) &super + 20 ) ) != 0 )
-               return 0;
-
-           super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
-           super.s_journal_block = 0;
-           super.s_version = 0;
-       }
-    }
-
-    DEBUG_F( "ReiserFS superblock data:\n" );
-    DEBUG_F( "Block count: %lu\n", le32_to_cpu(super.s_block_count) )
-    DEBUG_F( "Free blocks: %lu\n", le32_to_cpu(super.s_free_blocks) );
-    DEBUG_F( "Journal block: %lu\n", le32_to_cpu(super.s_journal_block) );
-    DEBUG_F( "Journal size (in blocks): %lu\n",
-                                    le32_to_cpu(super.s_orig_journal_size) );
-    DEBUG_F( "Root block: %lu\n\n", le32_to_cpu(super.s_root_block) );
-
-
-    INFO->version = le16_to_cpu(super.s_version);
-    INFO->blocksize = le16_to_cpu(super.s_blocksize);
-    INFO->blocksize_shift = log2( INFO->blocksize );
-
-    INFO->journal_block = le32_to_cpu(super.s_journal_block);
-    INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
-
-    INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;
-
-    /* At this point, we've found a valid superblock. If we run into problems
-     * mounting the FS, the user should probably know. */
-
-    /* A few sanity checks ... */
-    if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
-    {
-        prom_printf( "ReiserFS: Unsupported version field: %u\n",
-                     INFO->version );
-       return 0;
-    }
-
-    if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
-       || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
-    {
-        prom_printf( "ReiserFS: Unsupported block size: %u\n",
-                     INFO->blocksize );
-       return 0;
-    }
-
-    /* Setup the journal.. */
-    if ( INFO->journal_block != 0 )
-    {
-       if ( !is_power_of_two( INFO->journal_block_count ) )
-        {
-            prom_printf( "ReiserFS: Unsupported journal size, "
-                         "not a power of 2: %lu\n",
-                         INFO->journal_block_count );
-           return 0;
-        }
-
-       journal_init();
-       /* Read in super block again, maybe it is in the journal */
-       block_read( superblock, 0, sizeof (struct reiserfs_super_block),
-                    (char *) &super );
-    }
-
-    /* Read in the root block */
-    if ( !block_read( le32_to_cpu(super.s_root_block), 0,
-            INFO->blocksize, ROOT ) )
-    {
-        prom_printf( "ReiserFS: Failed to read in root block\n" );
-       return 0;
-    }
-
-    /* The root node is always the "deepest", so we can
-       determine the hieght of the tree using it. */
-    INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));
-
-
-    DEBUG_F( "root read_in: block=%u, depth=%u\n",
-       le32_to_cpu(super.s_root_block), INFO->tree_depth );
-
-    if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
-    {
-        prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
-                 INFO->tree_depth );
-       return 0;
-    }
-
-    if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
-    {
-       /* There is only one node in the whole filesystem, which is
-          simultanously leaf and root */
-       memcpy( LEAF, ROOT, INFO->blocksize );
-    }
-    return 1;
+     struct reiserfs_super_block super;
+     __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;
+
+     if (read_disk_block(INFO->file, superblock, 0, sizeof(super), &super) != sizeof(super)) {
+         DEBUG_F("read_disk_block failed!\n");
+         return 0;
+     }
+
+     DEBUG_F( "Found super->magic: \"%s\"\n", super.s_magic );
+
+     if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+        strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+     {
+         /* Try old super block position */
+         superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;
+
+         if (read_disk_block( INFO->file, superblock, 0, sizeof (super),  &super ) != sizeof(super)) {
+              DEBUG_F("read_disk_block failed!\n");
+              return 0;
+         }
+
+         if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+              strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+         {
+              /* pre journaling super block - untested */
+              if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
+                           (char *) ((__u32) &super + 20 ) ) != 0 )
+                   return 0;
+
+              super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
+              super.s_journal_block = 0;
+              super.s_version = 0;
+         }
+     }
+
+     DEBUG_F( "ReiserFS superblock data:\n" );
+     DEBUG_F( "Block count: %u\n", le32_to_cpu(super.s_block_count) )
+         DEBUG_F( "Free blocks: %u\n", le32_to_cpu(super.s_free_blocks) );
+     DEBUG_F( "Journal block: %u\n", le32_to_cpu(super.s_journal_block) );
+     DEBUG_F( "Journal size (in blocks): %u\n",
+             le32_to_cpu(super.s_orig_journal_size) );
+     DEBUG_F( "Root block: %u\n\n", le32_to_cpu(super.s_root_block) );
+
+
+     INFO->version = le16_to_cpu(super.s_version);
+     INFO->blocksize = le16_to_cpu(super.s_blocksize);
+     INFO->blocksize_shift = log2( INFO->blocksize );
+
+     INFO->journal_block = le32_to_cpu(super.s_journal_block);
+     INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
+
+     INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;
+
+     /* At this point, we've found a valid superblock. If we run into problems
+      * mounting the FS, the user should probably know. */
+
+     /* A few sanity checks ... */
+     if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
+     {
+         prom_printf( "ReiserFS: Unsupported version field: %u\n",
+                      INFO->version );
+         return 0;
+     }
+
+     if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
+         || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
+     {
+         prom_printf( "ReiserFS: Unsupported block size: %u\n",
+                      INFO->blocksize );
+         return 0;
+     }
+
+     /* Setup the journal.. */
+     if ( INFO->journal_block != 0 )
+     {
+         if ( !is_power_of_two( INFO->journal_block_count ) )
+         {
+              prom_printf( "ReiserFS: Unsupported journal size, "
+                           "not a power of 2: %u\n",
+                           INFO->journal_block_count );
+              return 0;
+         }
+
+         journal_init();
+         /* Read in super block again, maybe it is in the journal */
+         block_read( superblock, 0, sizeof (struct reiserfs_super_block),
+                     (char *) &super );
+     }
+
+     /* Read in the root block */
+     if ( !block_read( le32_to_cpu(super.s_root_block), 0,
+                      INFO->blocksize, ROOT ) )
+     {
+         prom_printf( "ReiserFS: Failed to read in root block\n" );
+         return 0;
+     }
+
+     /* The root node is always the "deepest", so we can
+       determine the hieght of the tree using it. */
+     INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));
+
+
+     DEBUG_F( "root read_in: block=%u, depth=%u\n",
+             le32_to_cpu(super.s_root_block), INFO->tree_depth );
+
+     if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
+     {
+         prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
+                      INFO->tree_depth );
+         return 0;
+     }
+
+     if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
+     {
+         /* There is only one node in the whole filesystem, which is
+            simultanously leaf and root */
+         memcpy( LEAF, ROOT, INFO->blocksize );
+     }
+     return 1;
 }
 
 /***************** TREE ACCESSING METHODS *****************************/
@@ -510,43 +523,43 @@ reiserfs_read_super( void )
 static char *
 read_tree_node( __u32 blockNr, __u16 depth )
 {
-    char *cache = CACHE(depth);
-    int num_cached = INFO->cached_slots;
-
-    if ( depth < num_cached )
-    {
-       /* This is the cached part of the path.
-           Check if same block is needed. */
-       if ( blockNr == INFO->blocks[depth] )
-           return cache;
-    }
-    else
-       cache = CACHE(num_cached);
-
-    DEBUG_F( "  next read_in: block=%u (depth=%u)\n", blockNr, depth );
-
-    if ( !block_read( blockNr, 0, INFO->blocksize, cache ) )
-    {
-        DEBUG_F( "block_read failed\n" );
-       return 0;
-    }
-
-    DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n",
-            blkh_level(BLOCKHEAD(cache)),
-            blkh_nr_item(BLOCKHEAD(cache)),
-            le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) );
-
-    /* Make sure it has the right node level */
-    if ( blkh_level(BLOCKHEAD(cache)) != depth )
-    {
-        DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth );
-        DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
-       errnum = FILE_ERR_BAD_FSYS;
-       return 0;
-    }
-
-    INFO->blocks[depth] = blockNr;
-    return cache;
+     char *cache = CACHE(depth);
+     int num_cached = INFO->cached_slots;
+
+     if ( depth < num_cached )
+     {
+         /* This is the cached part of the path.
+            Check if same block is needed. */
+         if ( blockNr == INFO->blocks[depth] )
+              return cache;
+     }
+     else
+         cache = CACHE(num_cached);
+
+     DEBUG_F( "  next read_in: block=%u (depth=%u)\n", blockNr, depth );
+
+     if ( !block_read( blockNr, 0, INFO->blocksize, cache ) )
+     {
+         DEBUG_F( "block_read failed\n" );
+         return 0;
+     }
+
+     DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n",
+             blkh_level(BLOCKHEAD(cache)),
+             blkh_nr_item(BLOCKHEAD(cache)),
+             le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) );
+
+     /* Make sure it has the right node level */
+     if ( blkh_level(BLOCKHEAD(cache)) != depth )
+     {
+         DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth );
+         DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+         errnum = FILE_ERR_BAD_FSYS;
+         return 0;
+     }
+
+     INFO->blocks[depth] = blockNr;
+     return cache;
 }
 
 /* Get the next key, i.e. the key following the last retrieved key in
@@ -555,88 +568,88 @@ read_tree_node( __u32 blockNr, __u16 depth )
 static int
 next_key( void )
 {
-    __u16 depth;
-    struct item_head *ih = INFO->current_ih + 1;
-    char *cache;
-
-
-    DEBUG_F( "next_key:\n  old ih: key %u:%u:%u:%u version:%u\n",
-       le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
-       le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
-       le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
-       le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
-       ih_version(INFO->current_ih) );
-
-
-    if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] )
-    {
-       depth = BLKH_LEVEL_LEAF;
-       /* The last item, was the last in the leaf node. * Read in the next
-        * * block */
-       do
-       {
-           if ( depth == INFO->tree_depth )
-           {
-               /* There are no more keys at all. * Return a dummy item with
-                * * MAX_KEY */
-               ih =
-                   ( struct item_head * )
-                   &BLOCKHEAD( LEAF )->blk_right_delim_key;
-               goto found;
-           }
-           depth++;
-
-           DEBUG_F( "  depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] );
-
-       }
-       while ( INFO->next_key_nr[depth] == 0 );
-
-       if ( depth == INFO->tree_depth )
-           cache = ROOT;
-       else if ( depth <= INFO->cached_slots )
-           cache = CACHE( depth );
-       else
-       {
-           cache = read_tree_node( INFO->blocks[depth], --depth );
-           if ( !cache )
-               return 0;
-       }
-
-       do
-       {
-           __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
-           int key_nr = INFO->next_key_nr[depth]++;
-
-
-           DEBUG_F( "  depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
-
-           if ( key_nr == nr_item )
-               /* This is the last item in this block, set the next_key_nr * 
-                * to 0 */
-               INFO->next_key_nr[depth] = 0;
-
-           cache =
-               read_tree_node( dc_block_number( &(DC( cache )[key_nr])),
-               --depth );
-           if ( !cache )
-               return 0;
-       }
-       while ( depth > BLKH_LEVEL_LEAF );
-
-       ih = ITEMHEAD;
-    }
-  found:
-    INFO->current_ih = ih;
-    INFO->current_item = &LEAF[ih_location(ih)];
-
-    DEBUG_F( "  new ih: key %u:%u:%u:%u version:%u\n",
-       le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
-       le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
-       le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
-       le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
-       ih_version(INFO->current_ih) );
-
-    return 1;
+     __u16 depth;
+     struct item_head *ih = INFO->current_ih + 1;
+     char *cache;
+
+
+     DEBUG_F( "next_key:\n  old ih: key %u:%u:%u:%u version:%u\n",
+             le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+             le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+             le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+             le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+             ih_version(INFO->current_ih) );
+
+
+     if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] )
+     {
+         depth = BLKH_LEVEL_LEAF;
+         /* The last item, was the last in the leaf node. * Read in the next
+          * * block */
+         do
+         {
+              if ( depth == INFO->tree_depth )
+              {
+                   /* There are no more keys at all. * Return a dummy item with
+                    * * MAX_KEY */
+                   ih =
+                        ( struct item_head * )
+                        &BLOCKHEAD( LEAF )->blk_right_delim_key;
+                   goto found;
+              }
+              depth++;
+
+              DEBUG_F( "  depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] );
+
+         }
+         while ( INFO->next_key_nr[depth] == 0 );
+
+         if ( depth == INFO->tree_depth )
+              cache = ROOT;
+         else if ( depth <= INFO->cached_slots )
+              cache = CACHE( depth );
+         else
+         {
+              cache = read_tree_node( INFO->blocks[depth], --depth );
+              if ( !cache )
+                   return 0;
+         }
+
+         do
+         {
+              __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+              int key_nr = INFO->next_key_nr[depth]++;
+
+
+              DEBUG_F( "  depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
+
+              if ( key_nr == nr_item )
+                   /* This is the last item in this block, set the next_key_nr * 
+                    * to 0 */
+                   INFO->next_key_nr[depth] = 0;
+
+              cache =
+                   read_tree_node( dc_block_number( &(DC( cache )[key_nr])),
+                                   --depth );
+              if ( !cache )
+                   return 0;
+         }
+         while ( depth > BLKH_LEVEL_LEAF );
+
+         ih = ITEMHEAD;
+     }
+found:
+     INFO->current_ih = ih;
+     INFO->current_item = &LEAF[ih_location(ih)];
+
+     DEBUG_F( "  new ih: key %u:%u:%u:%u version:%u\n",
+             le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+             le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+             le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+             le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+             ih_version(INFO->current_ih) );
+
+     return 1;
 }
 
 /* preconditions: reiserfs_read_super already executed, therefore 
@@ -652,155 +665,155 @@ next_key( void )
 static int
 search_stat( __u32 dir_id, __u32 objectid )
 {
-    char *cache;
-    int depth;
-    int nr_item;
-    int i;
-    struct item_head *ih;
+     char *cache;
+     int depth;
+     int nr_item;
+     int i;
+     struct item_head *ih;
 
 
-    DEBUG_F( "search_stat:\n  key %u:%u:0:0\n", le32_to_cpu(dir_id),
-            le32_to_cpu(objectid) );
+     DEBUG_F( "search_stat:\n  key %u:%u:0:0\n", le32_to_cpu(dir_id),
+             le32_to_cpu(objectid) );
 
 
-    depth = INFO->tree_depth;
-    cache = ROOT;
+     depth = INFO->tree_depth;
+     cache = ROOT;
 
-    DEBUG_F( "depth = %d\n", depth );
-    while ( depth > BLKH_LEVEL_LEAF )
-    {
-       struct key *key;
+     DEBUG_F( "depth = %d\n", depth );
+     while ( depth > BLKH_LEVEL_LEAF )
+     {
+         struct key *key;
 
-       nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+         nr_item = blkh_nr_item(BLOCKHEAD( cache ));
 
-       key = KEY( cache );
+         key = KEY( cache );
 
-       for ( i = 0; i < nr_item; i++ )
-       {
-          if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id)
-              || (key->k_dir_id == dir_id
-                  && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid)
-                      || (key->k_objectid == objectid
-                          && (key->u.k_offset_v1.k_offset
-                              | key->u.k_offset_v1.k_uniqueness) > 0))))
-               break;
-           key++;
-       }
+         for ( i = 0; i < nr_item; i++ )
+         {
+              if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id)
+                  || (key->k_dir_id == dir_id
+                      && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid)
+                          || (key->k_objectid == objectid
+                              && (key->u.k_offset_v1.k_offset
+                                  | key->u.k_offset_v1.k_uniqueness) > 0))))
+                   break;
+              key++;
+         }
 
 
-       DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
+         DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
 
-       INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1;
-       cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth );
-       if ( !cache )
-           return 0;
-    }
+         INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1;
+         cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth );
+         if ( !cache )
+              return 0;
+     }
 
-    /* cache == LEAF */
-    nr_item = blkh_nr_item(BLOCKHEAD(LEAF));
-    ih = ITEMHEAD;
-    DEBUG_F( "nr_item = %d\n", nr_item );
-    for ( i = 0; i < nr_item; i++ )
-    {
-       if ( ih->ih_key.k_dir_id == dir_id
-           && ih->ih_key.k_objectid == objectid
-           && ih->ih_key.u.k_offset_v1.k_offset == 0
-           && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 )
-       {
+     /* cache == LEAF */
+     nr_item = blkh_nr_item(BLOCKHEAD(LEAF));
+     ih = ITEMHEAD;
+     DEBUG_F( "nr_item = %d\n", nr_item );
+     for ( i = 0; i < nr_item; i++ )
+     {
+         if ( ih->ih_key.k_dir_id == dir_id
+              && ih->ih_key.k_objectid == objectid
+              && ih->ih_key.u.k_offset_v1.k_offset == 0
+              && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 )
+         {
 
-           DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
+              DEBUG_F( "  depth=%d, i=%d/%d\n", depth, i, nr_item );
 
-           INFO->current_ih = ih;
-           INFO->current_item = &LEAF[ih_location(ih)];
+              INFO->current_ih = ih;
+              INFO->current_item = &LEAF[ih_location(ih)];
 
-           return 1;
-       }
+              return 1;
+         }
 
-       ih++;
-    }
+         ih++;
+     }
 
-    DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
-    errnum = FILE_ERR_BAD_FSYS;
-    return 0;
+     DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+     errnum = FILE_ERR_BAD_FSYS;
+     return 0;
 }
 
 static int
 reiserfs_read_data( char *buf, __u32 len )
 {
-    __u32 blocksize;
-    __u32 offset;
-    __u32 to_read;
-    char *prev_buf = buf;
+     __u32 blocksize;
+     __u32 offset;
+     __u32 to_read;
+     char *prev_buf = buf;
 
 
-    DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
-       INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
+     DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
+             INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
 
 
-    if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
-       || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
-    {
-       search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
-       goto get_next_key;
-    }
+     if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
+         || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
+     {
+         search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
+         goto get_next_key;
+     }
 
-    while ( errnum == 0 )
-    {
-       if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
-           break;
+     while ( errnum == 0 )
+     {
+         if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
+              break;
 
-       offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
-       blocksize = ih_item_len(INFO->current_ih);
+         offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
+         blocksize = ih_item_len(INFO->current_ih);
 
 
-       DEBUG_F( "  loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
-           INFO->file->pos, len, offset, blocksize );
+         DEBUG_F( "  loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
+                  INFO->file->pos, len, offset, blocksize );
 
 
-       if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
-           && offset < blocksize )
-       {
-           to_read = blocksize - offset;
-           if ( to_read > len )
-               to_read = len;
-
-            memcpy( buf, INFO->current_item + offset, to_read );
-           goto update_buf_len;
-       }
-       else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
-       {
-           blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;
-
-           while ( offset < blocksize )
-           {
-               __u32 blocknr = le32_to_cpu(((__u32 *)
-                    INFO->current_item)[offset >> INFO->blocksize_shift]);
-
-               int blk_offset = offset & (INFO->blocksize - 1);
-
-               to_read = INFO->blocksize - blk_offset;
-               if ( to_read > len )
+         if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
+              && offset < blocksize )
+         {
+              to_read = blocksize - offset;
+              if ( to_read > len )
                    to_read = len;
 
-               /* Journal is only for meta data.
-                   Data blocks can be read directly without using block_read */
-               read_disk_block( INFO->file, blocknr, blk_offset, to_read,
-                                 buf );
-
-             update_buf_len:
-               len -= to_read;
-               buf += to_read;
-               offset += to_read;
-               INFO->file->pos += to_read;
-               if ( len == 0 )
-                   goto done;
-           }
-       }
-      get_next_key:
-       next_key();
-    }
-  done:
-    return (errnum != 0) ? 0 : buf - prev_buf;
+              memcpy( buf, INFO->current_item + offset, to_read );
+              goto update_buf_len;
+         }
+         else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
+         {
+              blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;
+
+              while ( offset < blocksize )
+              {
+                   __u32 blocknr = le32_to_cpu(((__u32 *)
+                                                INFO->current_item)[offset >> INFO->blocksize_shift]);
+
+                   int blk_offset = offset & (INFO->blocksize - 1);
+
+                   to_read = INFO->blocksize - blk_offset;
+                   if ( to_read > len )
+                        to_read = len;
+
+                   /* Journal is only for meta data.
+                      Data blocks can be read directly without using block_read */
+                   read_disk_block( INFO->file, blocknr, blk_offset, to_read,
+                                    buf );
+
+              update_buf_len:
+                   len -= to_read;
+                   buf += to_read;
+                   offset += to_read;
+                   INFO->file->pos += to_read;
+                   if ( len == 0 )
+                        goto done;
+              }
+         }
+     get_next_key:
+         next_key();
+     }
+done:
+     return (errnum != 0) ? 0 : buf - prev_buf;
 }
 
 
@@ -814,212 +827,226 @@ reiserfs_read_data( char *buf, __u32 len )
 static int
 reiserfs_open_file( char *dirname )
 {
-    struct reiserfs_de_head *de_head;
-    char *rest, ch;
-    __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
+     struct reiserfs_de_head *de_head;
+     char *rest, ch;
+     __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
+
+     char linkbuf[PATH_MAX];   /* buffer for following symbolic links */
+     int link_count = 0;
+     int mode;
 
-    char linkbuf[PATH_MAX];    /* buffer for following symbolic links */
-    int link_count = 0;
-    int mode;
-
-    dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
-    objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
-
-    while ( 1 )
-    {
-
-       DEBUG_F( "dirname=%s\n", dirname );
-
-       /* Search for the stat info first. */
-       if ( !search_stat( dir_id, objectid ) )
-           return 0;
-
-
-       DEBUG_F( "sd_mode=0%o sd_size=%u\n",
-           sd_mode((struct stat_data *) INFO->current_item ),
-           sd_size(INFO->current_ih, INFO->current_item ));
-
-
-        mode = sd_mode((struct stat_data *)INFO->current_item);
-
-       /* If we've got a symbolic link, then chase it. */
-       if ( S_ISLNK( mode ) )
-       {
-           int len = 0;
-
-           if ( ++link_count > MAX_LINK_COUNT )
-           {
-               errnum = FILE_ERR_SYMLINK_LOOP;
-               return 0;
-           }
-
-           /* Get the symlink size. */
-            INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
-
-           /* Find out how long our remaining name is. */
-           while ( dirname[len] && !isspace( dirname[len] ) )
-               len++;
-
-           if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
-           {
-               errnum = FILE_ERR_LENGTH;
-               return 0;
-           }
-
-           /* Copy the remaining name to the end of the symlink data. Note * 
-            * that DIRNAME and LINKBUF may overlap! */
-           memmove( linkbuf + INFO->file->len, dirname, len + 1 );
-
-           INFO->fileinfo.k_dir_id = dir_id;
-           INFO->fileinfo.k_objectid = objectid;
-           INFO->file->pos = 0;
-           if ( !next_key()
-               || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len )
-               return 0;
-
-
-           DEBUG_F( "symlink=%s\n", linkbuf );
-
-
-           dirname = linkbuf;
-           if ( *dirname == '/' )
-           {
-               /* It's an absolute link, so look it up in root. */
-               dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
-               objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
-           }
-           else
-           {
-               /* Relative, so look it up in our parent directory. */
-               dir_id = parent_dir_id;
-               objectid = parent_objectid;
-           }
-
-           /* Now lookup the new name. */
-           continue;
-       }
-
-       /* if we have a real file (and we're not just printing *
-        * possibilities), then this is where we want to exit */
-
-       if ( !*dirname || isspace( *dirname ) )
-       {
-           if ( !S_ISREG( mode ) )
-           {
-               errnum = FILE_ERR_BAD_TYPE;
-               return 0;
-           }
-
-           INFO->file->pos = 0;
-            INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
-
-           INFO->fileinfo.k_dir_id = dir_id;
-           INFO->fileinfo.k_objectid = objectid;
-           return next_key();
-       }
-
-       /* continue with the file/directory name interpretation */
-       while ( *dirname == '/' )
-           dirname++;
-       if ( !S_ISDIR( mode ) )
-       {
-           errnum = FILE_ERR_BAD_TYPE;
-           return 0;
-       }
-       for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
-           rest++ ) ;
-       *rest = 0;
-
-       while ( 1 )
-       {
-           char *name_end;
-           int num_entries;
-
-           if ( !next_key() )
-               return 0;
-
-           if ( INFO->current_ih->ih_key.k_objectid != objectid )
-               break;
-
-           name_end = INFO->current_item + ih_item_len(INFO->current_ih);
-           de_head = ( struct reiserfs_de_head * ) INFO->current_item;
-           num_entries = ih_entry_count(INFO->current_ih);
-           while ( num_entries > 0 )
-           {
-               char *filename = INFO->current_item + deh_location(de_head);
-               char tmp = *name_end;
-
-                if( deh_state(de_head) & (1 << DEH_Visible))
-               {
-                   int cmp;
-
-                   /* Directory names in ReiserFS are not null * terminated. 
-                    * We write a temporary 0 behind it. * NOTE: that this
-                    * may overwrite the first block in * the tree cache.
-                    * That doesn't hurt as long as we * don't call next_key
-                    * () in between. */
-                   *name_end = 0;
-                   cmp = strcmp( dirname, filename );
-                   *name_end = tmp;
-                   if ( cmp == 0 )
-                       goto found;
-               }
-               /* The beginning of this name marks the end of the next name. 
-                */
-               name_end = filename;
-               de_head++;
-               num_entries--;
-           }
-       }
-
-       errnum = FILE_ERR_NOTFOUND;
-       *rest = ch;
-       return 0;
-
-      found:
-       *rest = ch;
-       dirname = rest;
-
-       parent_dir_id = dir_id;
-       parent_objectid = objectid;
-       dir_id = de_head->deh_dir_id; /* LE */
-       objectid = de_head->deh_objectid; /* LE */
-    }
+     dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+     objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+
+     while ( 1 )
+     {
+
+         DEBUG_F( "dirname=%s\n", dirname );
+
+         /* Search for the stat info first. */
+         if ( !search_stat( dir_id, objectid ) )
+              return 0;
+
+
+         DEBUG_F( "sd_mode=0%o sd_size=%Lu\n",
+                  sd_mode((struct stat_data *) INFO->current_item ),
+                  sd_size(INFO->current_ih, INFO->current_item ));
+
+
+         mode = sd_mode((struct stat_data *)INFO->current_item);
+
+         /* If we've got a symbolic link, then chase it. */
+         if ( S_ISLNK( mode ) )
+         {
+              int len = 0;
+
+              DEBUG_F("link count = %d\n", link_count);
+              DEBUG_SLEEP;
+              if ( ++link_count > MAX_LINK_COUNT )
+              {
+                   DEBUG_F("Symlink loop\n");
+                   errnum = FILE_ERR_SYMLINK_LOOP;
+                   return 0;
+              }
+
+              /* Get the symlink size. */
+              INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+              /* Find out how long our remaining name is. */
+              while ( dirname[len] && !isspace( dirname[len] ) )
+                   len++;
+
+              if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
+              {
+                   errnum = FILE_ERR_LENGTH;
+                   return 0;
+              }
+
+              /* Copy the remaining name to the end of the symlink data. Note * 
+               * that DIRNAME and LINKBUF may overlap! */
+              memmove( linkbuf + INFO->file->len, dirname, len + 1 );
+
+              INFO->fileinfo.k_dir_id = dir_id;
+              INFO->fileinfo.k_objectid = objectid;
+              INFO->file->pos = 0;
+              if ( !next_key()
+                   || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len ) {
+                   DEBUG_F("reiserfs_open_file - if !next_key || reiserfs_read_data\n");
+                   DEBUG_SLEEP;
+                   errnum = FILE_IOERR;
+                   return 0;
+              }
+
+
+              DEBUG_F( "symlink=%s\n", linkbuf );
+              DEBUG_SLEEP;
+
+              dirname = linkbuf;
+              if ( *dirname == '/' )
+              {
+                   /* It's an absolute link, so look it up in root. */
+                   dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+                   objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+              }
+              else
+              {
+                   /* Relative, so look it up in our parent directory. */
+                   dir_id = parent_dir_id;
+                   objectid = parent_objectid;
+              }
+
+              /* Now lookup the new name. */
+              continue;
+         }
+
+         /* if we have a real file (and we're not just printing *
+          * possibilities), then this is where we want to exit */
+
+         if ( !*dirname || isspace( *dirname ) )
+         {
+              if ( !S_ISREG( mode ) )
+              {
+                   errnum = FILE_ERR_BAD_TYPE;
+                   return 0;
+              }
+
+              INFO->file->pos = 0;
+              INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+              INFO->fileinfo.k_dir_id = dir_id;
+              INFO->fileinfo.k_objectid = objectid;
+              return next_key();
+         }
+
+         /* continue with the file/directory name interpretation */
+         while ( *dirname == '/' )
+              dirname++;
+         if ( !S_ISDIR( mode ) )
+         {
+              errnum = FILE_ERR_NOTDIR;
+              return 0;
+         }
+         for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
+               rest++ ) ;
+         *rest = 0;
+
+         while ( 1 )
+         {
+              char *name_end;
+              int num_entries;
+
+              if ( !next_key() )
+                   return 0;
+
+              if ( INFO->current_ih->ih_key.k_objectid != objectid )
+                   break;
+
+              name_end = INFO->current_item + ih_item_len(INFO->current_ih);
+              de_head = ( struct reiserfs_de_head * ) INFO->current_item;
+              num_entries = ih_entry_count(INFO->current_ih);
+              while ( num_entries > 0 )
+              {
+                   char *filename = INFO->current_item + deh_location(de_head);
+                   char tmp = *name_end;
+
+                   if( deh_state(de_head) & (1 << DEH_Visible))
+                   {
+                        int cmp;
+
+                        /* Directory names in ReiserFS are not null * terminated. 
+                         * We write a temporary 0 behind it. * NOTE: that this
+                         * may overwrite the first block in * the tree cache.
+                         * That doesn't hurt as long as we * don't call next_key
+                         * () in between. */
+                        *name_end = 0;
+                        cmp = strcmp( dirname, filename );
+                        *name_end = tmp;
+                        if ( cmp == 0 )
+                             goto found;
+                   }
+                   /* The beginning of this name marks the end of the next name. 
+                    */
+                   name_end = filename;
+                   de_head++;
+                   num_entries--;
+              }
+         }
+
+         errnum = FILE_ERR_NOTFOUND;
+         *rest = ch;
+         return 0;
+
+     found:
+         *rest = ch;
+         dirname = rest;
+
+         parent_dir_id = dir_id;
+         parent_objectid = objectid;
+         dir_id = de_head->deh_dir_id; /* LE */
+         objectid = de_head->deh_objectid; /* LE */
+     }
 }
 
 
 
 #ifndef __LITTLE_ENDIAN
 typedef union {
-    struct offset_v2 offset_v2;
-    __u64 linear;
+     struct offset_v2 offset_v2;
+     __u64 linear;
 } offset_v2_esafe_overlay;
 
 inline __u16
 offset_v2_k_type( struct offset_v2 *v2 )
 {
-    offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
-    tmp.linear = le64_to_cpu( tmp.linear );
-    return tmp.offset_v2.k_type;
+     offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+     tmp.linear = le64_to_cpu( tmp.linear );
+     return tmp.offset_v2.k_type;
 }
  
 inline loff_t
 offset_v2_k_offset( struct offset_v2 *v2 )
 {
-    offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
-    tmp.linear = le64_to_cpu( tmp.linear );
-    return tmp.offset_v2.k_offset;
+     offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+     tmp.linear = le64_to_cpu( tmp.linear );
+     return tmp.offset_v2.k_offset;
 }
 #endif
 
 inline int
 uniqueness2type (__u32 uniqueness)
 {
-    switch (uniqueness) {
-    case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
-    case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
-    case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
-    case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
-    }
-    return TYPE_ANY;
+     switch (uniqueness) {
+     case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
+     case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
+     case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
+     case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
+     }
+     return TYPE_ANY;
 }
+
+/* 
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
diff --git a/second/fs_xfs.c b/second/fs_xfs.c
new file mode 100644 (file)
index 0000000..866ceac
--- /dev/null
@@ -0,0 +1,800 @@
+/*
+ *  fsys_xfs.c - an implementation for the SGI XFS file system
+ *
+ *  Copyright (C) 2001  Ethan Benson
+ *
+ *  Adapted from Grub
+ *
+ *  Copyright (C) 2001  Serguei Tzukanov
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "types.h"
+#include "ctype.h"
+#include "string.h"
+#include "stdlib.h"
+#include "fs.h"
+#include "xfs/xfs.h"
+#include "errors.h"
+
+#define SECTOR_BITS 9
+
+int xfs_mount (void);
+int xfs_read_data (char *buf, int len);
+int xfs_dir (char *dirname);
+
+/* Exported in struct fs_t */
+static int xfs_open(struct boot_file_t *file, const char *dev_name,
+                   struct partition_t *part, const char *file_name);
+static int xfs_read(struct boot_file_t *file, unsigned int size, void *buffer);
+static int xfs_seek(struct boot_file_t *file, unsigned int newpos);
+static int xfs_close(struct boot_file_t *file);
+
+struct fs_t xfs_filesystem = {
+       name:"xfs",
+       open:xfs_open,
+       read:xfs_read,
+       seek:xfs_seek,
+       close:xfs_close
+};
+
+struct boot_file_t *xfs_file;
+static char FSYS_BUF[32768];
+__u64 partition_offset;
+int errnum;
+
+static int
+xfs_open(struct boot_file_t *file, const char *dev_name,
+        struct partition_t *part, const char *file_name)
+{
+       static char buffer[1024];
+
+       DEBUG_ENTER;
+       DEBUG_OPEN;
+
+       if (part)
+       {
+               DEBUG_F("Determining offset for partition %d\n", part->part_number);
+               partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
+               DEBUG_F("%Lu = %lu * %hu\n", partition_offset,
+                       part->part_start,
+                       part->blocksize);
+       }
+       else
+               partition_offset = 0;
+
+       sprintf(buffer, "%s:%d", dev_name, 0); /* 0 is full disk in OF */
+       DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
+               buffer, file_name, partition_offset);
+       file->of_device = prom_open(buffer);
+
+       if (file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL)
+       {
+               DEBUG_F("Can't open device %p\n", file->of_device);
+               DEBUG_LEAVE(FILE_ERR_BADDEV);
+               return FILE_ERR_BADDEV;
+       }
+
+       DEBUG_F("%p was successfully opened\n", file->of_device);
+
+       xfs_file = file;
+    
+       if (xfs_mount() != 1)
+       {
+               DEBUG_F("Couldn't open XFS @ %s/%Lu\n", buffer, partition_offset);
+               prom_close(file->of_device);
+               DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+               DEBUG_SLEEP;
+               return FILE_ERR_BAD_FSYS;
+       }
+
+       DEBUG_F("Attempting to open %s\n", file_name);
+       strcpy(buffer, file_name); /* xfs_dir modifies argument */
+       if(!xfs_dir(buffer))
+       {
+               DEBUG_F("xfs_dir() failed. errnum = %d\n", errnum);
+               prom_close( file->of_device );
+               DEBUG_LEAVE_F(errnum);
+               DEBUG_SLEEP;
+               return errnum;
+       }
+
+       DEBUG_F("Successfully opened %s\n", file_name);
+
+       DEBUG_LEAVE(FILE_ERR_OK);
+       return FILE_ERR_OK;
+}
+
+static int
+xfs_read(struct boot_file_t *file, unsigned int size, void *buffer)
+{
+       return xfs_read_data(buffer, size);
+}
+
+static int
+xfs_seek(struct boot_file_t *file, unsigned int newpos)
+{
+       file->pos = newpos;
+       return FILE_ERR_OK;
+}
+
+static int
+xfs_close(struct boot_file_t *file)
+{
+       if(file->of_device)
+       {
+               prom_close(file->of_device);
+               file->of_device = 0;
+               DEBUG_F("xfs_close called\n");
+       }
+       return FILE_ERR_OK;
+}
+
+static int
+read_disk_block(struct boot_file_t *file, __u32 block, __u32 start,
+               __u32 length, void *buf)
+{
+       unsigned long long pos = block * 512;
+       pos += partition_offset + start;
+       DEBUG_F("Reading %u bytes, starting at block %u, disk offset %Lu\n",
+               length, block, pos);
+       if (!prom_lseek(file->of_device, pos)) {
+               DEBUG_F("prom_lseek failed\n");
+               return 0;
+       }
+       return prom_read(file->of_device, buf, length);
+}
+
+#define MAX_LINK_COUNT 8
+
+typedef struct xad {
+       xfs_fileoff_t offset;
+       xfs_fsblock_t start;
+       xfs_filblks_t len;
+} xad_t;
+
+struct xfs_info {
+       int bsize;
+       int dirbsize;
+       int isize;
+       unsigned int agblocks;
+       int bdlog;
+       int blklog;
+       int inopblog;
+       int agblklog;
+       int agnolog;
+       int dirblklog;
+       unsigned int nextents;
+       xfs_daddr_t next;
+       xfs_daddr_t daddr;
+       xfs_dablk_t forw;
+       xfs_dablk_t dablk;
+       xfs_bmbt_rec_32_t *xt;
+       xfs_bmbt_ptr_t ptr0;
+       int btnode_ptr0_off;
+       int i8param;
+       int dirpos;
+       int dirmax;
+       int blkoff;
+       int fpos;
+       xfs_ino_t rootino;
+};
+
+static struct xfs_info xfs;
+
+#define dirbuf         ((char *)FSYS_BUF)
+#define filebuf                ((char *)FSYS_BUF + 4096)
+#define inode          ((xfs_dinode_t *)((char *)FSYS_BUF + 8192))
+#define icore          (inode->di_core)
+
+#define        mask32lo(n)     (((__uint32_t)1 << (n)) - 1)
+
+#define        XFS_INO_MASK(k)         ((__uint32_t)((1ULL << (k)) - 1))
+#define        XFS_INO_OFFSET_BITS     xfs.inopblog
+#define        XFS_INO_AGBNO_BITS      xfs.agblklog
+#define        XFS_INO_AGINO_BITS      (xfs.agblklog + xfs.inopblog)
+#define        XFS_INO_AGNO_BITS       xfs.agnolog
+
+static inline xfs_agblock_t
+agino2agbno (xfs_agino_t agino)
+{
+       return agino >> XFS_INO_OFFSET_BITS;
+}
+
+static inline xfs_agnumber_t
+ino2agno (xfs_ino_t ino)
+{
+       return ino >> XFS_INO_AGINO_BITS;
+}
+
+static inline xfs_agino_t
+ino2agino (xfs_ino_t ino)
+{
+       return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS);
+}
+
+static inline int
+ino2offset (xfs_ino_t ino)
+{
+       return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS);
+}
+
+/* XFS is big endian, powerpc is big endian */
+
+static inline __const__ __uint16_t
+le16 (__uint16_t x)
+{
+       return x;
+}
+
+static inline __const__ __uint32_t
+le32 (__uint32_t x)
+{
+       return x;
+}
+
+static inline __const__ __uint64_t
+le64 (__uint64_t x)
+{
+       return x;
+}
+
+static xfs_fsblock_t
+xt_start (xfs_bmbt_rec_32_t *r)
+{
+       return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | 
+              (((xfs_fsblock_t)le32 (r->l2)) << 11) |
+              (((xfs_fsblock_t)le32 (r->l3)) >> 21);
+}
+
+static xfs_fileoff_t
+xt_offset (xfs_bmbt_rec_32_t *r)
+{
+       return (((xfs_fileoff_t)le32 (r->l0) &
+               mask32lo(31)) << 23) |
+               (((xfs_fileoff_t)le32 (r->l1)) >> 9);
+}
+
+static xfs_filblks_t
+xt_len (xfs_bmbt_rec_32_t *r)
+{
+       return le32(r->l3) & mask32lo(21);
+}
+
+static const char xfs_highbit[256] = {
+       -1, 0, 1, 1, 2, 2, 2, 2,                        /* 00 .. 07 */
+       3, 3, 3, 3, 3, 3, 3, 3,                 /* 08 .. 0f */
+       4, 4, 4, 4, 4, 4, 4, 4,                 /* 10 .. 17 */
+       4, 4, 4, 4, 4, 4, 4, 4,                 /* 18 .. 1f */
+       5, 5, 5, 5, 5, 5, 5, 5,                 /* 20 .. 27 */
+       5, 5, 5, 5, 5, 5, 5, 5,                 /* 28 .. 2f */
+       5, 5, 5, 5, 5, 5, 5, 5,                 /* 30 .. 37 */
+       5, 5, 5, 5, 5, 5, 5, 5,                 /* 38 .. 3f */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 40 .. 47 */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 48 .. 4f */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 50 .. 57 */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 58 .. 5f */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 60 .. 67 */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 68 .. 6f */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 70 .. 77 */
+       6, 6, 6, 6, 6, 6, 6, 6,                 /* 78 .. 7f */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* 80 .. 87 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* 88 .. 8f */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* 90 .. 97 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* 98 .. 9f */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* a0 .. a7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* a8 .. af */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* b0 .. b7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* b8 .. bf */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* c0 .. c7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* c8 .. cf */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* d0 .. d7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* d8 .. df */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* e0 .. e7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* e8 .. ef */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* f0 .. f7 */
+       7, 7, 7, 7, 7, 7, 7, 7,                 /* f8 .. ff */
+};
+
+static int
+xfs_highbit32(__uint32_t v)
+{
+       int             i;
+
+       if (v & 0xffff0000)
+               if (v & 0xff000000)
+                       i = 24;
+               else
+                       i = 16;
+       else if (v & 0x0000ffff)
+               if (v & 0x0000ff00)
+                       i = 8;
+               else
+                       i = 0;
+       else
+               return -1;
+       return i + xfs_highbit[(v >> i) & 0xff];
+}
+
+static int
+isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len)
+{
+       return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
+}
+
+static xfs_daddr_t
+agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno)
+{
+       return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog;
+}
+
+static xfs_daddr_t
+fsb2daddr (xfs_fsblock_t fsbno)
+{
+       return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog),
+                        (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog)));
+}
+
+static inline int
+btroot_maxrecs (void)
+{
+       int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize;
+
+       return (tmp - sizeof(xfs_bmdr_block_t) -
+               (int)((char *)&inode->di_u - (char*)inode)) /
+               (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t));
+}
+
+static int
+di_read (xfs_ino_t ino)
+{
+       xfs_agino_t agino;
+       xfs_agnumber_t agno;
+       xfs_agblock_t agbno;
+       xfs_daddr_t daddr;
+       int offset;
+
+       agno = ino2agno (ino);
+       agino = ino2agino (ino);
+       agbno = agino2agbno (agino);
+       offset = ino2offset (ino);
+       daddr = agb2daddr (agno, agbno);
+
+       read_disk_block(xfs_file, daddr, offset*xfs.isize, xfs.isize, (char *)inode);
+
+       xfs.ptr0 = *(xfs_bmbt_ptr_t *)
+                   (inode->di_u.di_c + sizeof(xfs_bmdr_block_t)
+                   + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t));
+
+       return 1;
+}
+
+static void
+init_extents (void)
+{
+       xfs_bmbt_ptr_t ptr0;
+       xfs_btree_lblock_t h;
+
+       switch (icore.di_format) {
+       case XFS_DINODE_FMT_EXTENTS:
+               xfs.xt = inode->di_u.di_bmx;
+               xfs.nextents = le32 (icore.di_nextents);
+               break;
+       case XFS_DINODE_FMT_BTREE:
+               ptr0 = xfs.ptr0;
+               for (;;) {
+                       xfs.daddr = fsb2daddr (le64(ptr0));
+                       read_disk_block(xfs_file, xfs.daddr, 0,
+                                       sizeof(xfs_btree_lblock_t), (char *)&h);
+                       if (!h.bb_level) {
+                               xfs.nextents = le16(h.bb_numrecs);
+                               xfs.next = fsb2daddr (le64(h.bb_leftsib));
+                               xfs.fpos = sizeof(xfs_btree_block_t);
+                               return;
+                       }
+                       read_disk_block(xfs_file, xfs.daddr, xfs.btnode_ptr0_off,
+                                sizeof(xfs_bmbt_ptr_t), (char *)&ptr0);
+               }
+       }
+}
+
+static xad_t *
+next_extent (void)
+{
+       static xad_t xad;
+
+       switch (icore.di_format) {
+       case XFS_DINODE_FMT_EXTENTS:
+               if (xfs.nextents == 0)
+                       return NULL;
+               break;
+       case XFS_DINODE_FMT_BTREE:
+               if (xfs.nextents == 0) {
+                       xfs_btree_lblock_t h;
+                       if (xfs.next == 0)
+                               return NULL;
+                       xfs.daddr = xfs.next;
+                       read_disk_block(xfs_file, xfs.daddr, 0,
+                                       sizeof(xfs_btree_lblock_t), (char *)&h);
+                       xfs.nextents = le16(h.bb_numrecs);
+                       xfs.next = fsb2daddr (le64(h.bb_leftsib));
+                       xfs.fpos = sizeof(xfs_btree_block_t);
+               }
+               /* Yeah, I know that's slow, but I really don't care */
+               read_disk_block(xfs_file, xfs.daddr, xfs.fpos,
+                               sizeof(xfs_bmbt_rec_t), filebuf);
+               xfs.xt = (xfs_bmbt_rec_32_t *)filebuf;
+               xfs.fpos += sizeof(xfs_bmbt_rec_32_t);
+               break;
+       default:
+               return NULL;
+       }
+       xad.offset = xt_offset (xfs.xt);
+       xad.start = xt_start (xfs.xt);
+       xad.len = xt_len (xfs.xt);
+       ++xfs.xt;
+       --xfs.nextents;
+
+       return &xad;
+}
+
+/*
+ * Name lies - the function reads only first 100 bytes
+ */
+static void
+xfs_dabread (void)
+{
+       xad_t *xad;
+       xfs_fileoff_t offset;;
+
+       init_extents ();
+       while ((xad = next_extent ())) {
+               offset = xad->offset;
+               if (isinxt (xfs.dablk, offset, xad->len)) {
+                       read_disk_block(xfs_file, fsb2daddr (xad->start + xfs.dablk - offset),
+                                       0, 100, dirbuf);
+                       break;
+               }
+       }
+}
+
+static inline xfs_ino_t
+sf_ino (char *sfe, int namelen)
+{
+       void *p = sfe + namelen + 3;
+
+       return (xfs.i8param == 0)
+               ? le64(*(xfs_ino_t *)p) : le32(*(__uint32_t *)p);
+}
+
+static inline xfs_ino_t
+sf_parent_ino (void)
+{
+       return (xfs.i8param == 0)
+               ? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent))
+               : le32(*(__uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent));
+}
+
+static inline int
+roundup8 (int n)
+{
+       return ((n+7)&~7);
+}
+
+static char *
+next_dentry (xfs_ino_t *ino)
+{
+       int namelen = 1;
+       int toread;
+       static char *usual[2] = {".", ".."};
+       static xfs_dir2_sf_entry_t *sfe;
+       char *name = usual[0];
+
+       if (xfs.dirpos >= xfs.dirmax) {
+               if (xfs.forw == 0)
+                       return NULL;
+               xfs.dablk = xfs.forw;
+               xfs_dabread ();
+#define h      ((xfs_dir2_leaf_hdr_t *)dirbuf)
+               xfs.dirmax = le16 (h->count) - le16 (h->stale);
+               xfs.forw = le32 (h->info.forw);
+#undef h
+               xfs.dirpos = 0;
+       }
+
+       switch (icore.di_format) {
+       case XFS_DINODE_FMT_LOCAL:
+               switch (xfs.dirpos) {
+               case -2:
+                       *ino = 0;
+                       break;
+               case -1:
+                       *ino = sf_parent_ino ();
+                       ++name;
+                       ++namelen;
+                       sfe = (xfs_dir2_sf_entry_t *)
+                               (inode->di_u.di_c 
+                                + sizeof(xfs_dir2_sf_hdr_t)
+                                - xfs.i8param);
+                       break;
+               default:
+                       namelen = sfe->namelen;
+                       *ino = sf_ino ((char *)sfe, namelen);
+                       name = sfe->name;
+                       sfe = (xfs_dir2_sf_entry_t *)
+                                 ((char *)sfe + namelen + 11 - xfs.i8param);
+               }
+               break;
+       case XFS_DINODE_FMT_BTREE:
+       case XFS_DINODE_FMT_EXTENTS:
+#define dau    ((xfs_dir2_data_union_t *)dirbuf)
+               for (;;) {
+                       if (xfs.blkoff >= xfs.dirbsize) {
+                               xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+                               xfs_file->pos &= ~(xfs.dirbsize - 1);
+                               xfs_file->pos |= xfs.blkoff;
+                       }
+                       xfs_read_data (dirbuf, 4);
+                       xfs.blkoff += 4;
+                       if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) {
+                               toread = roundup8 (le16(dau->unused.length)) - 4;
+                               xfs.blkoff += toread;
+                               xfs_file->pos += toread;
+                               continue;
+                       }
+                       break;
+               }
+               xfs_read_data ((char *)dirbuf + 4, 5);
+               *ino = le64 (dau->entry.inumber);
+               namelen = dau->entry.namelen;
+#undef dau
+               toread = roundup8 (namelen + 11) - 9;
+               xfs_read_data (dirbuf, toread);
+               name = (char *)dirbuf;
+               xfs.blkoff += toread + 5;
+               break;
+       }
+       ++xfs.dirpos;
+       name[namelen] = 0;
+
+       return name;
+}
+
+static char *
+first_dentry (xfs_ino_t *ino)
+{
+       xfs.forw = 0;
+       switch (icore.di_format) {
+       case XFS_DINODE_FMT_LOCAL:
+               xfs.dirmax = inode->di_u.di_dir2sf.hdr.count;
+               xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4;
+               xfs.dirpos = -2;
+               break;
+       case XFS_DINODE_FMT_EXTENTS:
+       case XFS_DINODE_FMT_BTREE:
+               xfs_file->pos = 0;
+               xfs_file->len = le64 (icore.di_size);
+               xfs_read_data (dirbuf, sizeof(xfs_dir2_data_hdr_t));
+               if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) {
+#define tail           ((xfs_dir2_block_tail_t *)dirbuf)
+                       xfs_file->pos = xfs.dirbsize - sizeof(*tail);
+                       xfs_read_data (dirbuf, sizeof(*tail));
+                       xfs.dirmax = le32 (tail->count) - le32 (tail->stale);
+#undef tail
+               } else {
+                       xfs.dablk = (1ULL << 35) >> xfs.blklog;
+#define h              ((xfs_dir2_leaf_hdr_t *)dirbuf)
+#define n              ((xfs_da_intnode_t *)dirbuf)
+                       for (;;) {
+                               xfs_dabread ();
+                               if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC))
+                                   || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) {
+                                       xfs.dirmax = le16 (h->count) - le16 (h->stale);
+                                       xfs.forw = le32 (h->info.forw);
+                                       break;
+                               }
+                               xfs.dablk = le32 (n->btree[0].before);
+                       }
+#undef n
+#undef h
+               }
+               xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+               xfs_file->pos = xfs.blkoff;
+               xfs.dirpos = 0;
+               break;
+       }
+       return next_dentry (ino);
+}
+
+int
+xfs_mount (void)
+{
+       xfs_sb_t super;
+
+       if (read_disk_block(xfs_file, 0, 0, sizeof(super), &super) != sizeof(super)) {
+               DEBUG_F("read_disk_block failed!\n");
+               return 0;
+       } else if (super.sb_magicnum != XFS_SB_MAGIC) {
+               DEBUG_F("xfs_mount: Bad magic: %x\n", super.sb_magicnum);
+               return 0;
+       } else if ((super.sb_versionnum & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) {
+               DEBUG_F("xfs_mount: Bad version: %x\n", super.sb_versionnum);
+               return 0;
+       }
+
+       xfs.bsize = le32 (super.sb_blocksize);
+       xfs.blklog = super.sb_blocklog;
+       xfs.bdlog = xfs.blklog - SECTOR_BITS;
+       xfs.rootino = le64 (super.sb_rootino);
+       xfs.isize = le16 (super.sb_inodesize);
+       xfs.agblocks = le32 (super.sb_agblocks);
+       xfs.dirblklog = super.sb_dirblklog;
+       xfs.dirbsize = xfs.bsize << super.sb_dirblklog;
+
+       xfs.inopblog = super.sb_inopblog;
+       xfs.agblklog = super.sb_agblklog;
+       xfs.agnolog = xfs_highbit32 (le32 (super.sb_agcount) - 1) + 1;
+
+       xfs.btnode_ptr0_off =
+               ((xfs.bsize - sizeof(xfs_btree_block_t)) /
+               (sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)))
+                * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t);
+
+       return 1;
+}
+
+int
+xfs_read_data (char *buf, int len)
+{
+       xad_t *xad;
+       xfs_fileoff_t endofprev, endofcur, offset;
+       xfs_filblks_t xadlen;
+       int toread, startpos, endpos;
+
+       if (icore.di_format == XFS_DINODE_FMT_LOCAL) {
+               memmove(buf, inode->di_u.di_c + xfs_file->pos, len);
+               xfs_file->pos += len;
+               return len;
+       }
+
+       startpos = xfs_file->pos;
+       endpos = xfs_file->pos + len;
+       if (endpos > xfs_file->len)
+               endpos = xfs_file->len;
+       endofprev = (xfs_fileoff_t)-1;
+       init_extents ();
+       while (len > 0 && (xad = next_extent ())) {
+               offset = xad->offset;
+               xadlen = xad->len;
+               if (isinxt (xfs_file->pos >> xfs.blklog, offset, xadlen)) {
+                       endofcur = (offset + xadlen) << xfs.blklog; 
+                       toread = (endofcur >= endpos)
+                                 ? len : (endofcur - xfs_file->pos);
+                       read_disk_block(xfs_file, fsb2daddr (xad->start),
+                                       xfs_file->pos - (offset << xfs.blklog), toread, buf);
+                       buf += toread;
+                       len -= toread;
+                       xfs_file->pos += toread;
+               } else if (offset > endofprev) {
+                       toread = ((offset << xfs.blklog) >= endpos)
+                                 ? len : ((offset - endofprev) << xfs.blklog);
+                       len -= toread;
+                       xfs_file->pos += toread;
+                       for (; toread; toread--) {
+                               *buf++ = 0;
+                       }
+                       continue;
+               }
+               endofprev = offset + xadlen; 
+       }
+
+       return xfs_file->pos - startpos;
+}
+
+int
+xfs_dir (char *dirname)
+{
+       xfs_ino_t ino, parent_ino, new_ino;
+       xfs_fsize_t di_size;
+       int di_mode;
+       int cmp, n, link_count;
+       char linkbuf[xfs.bsize];
+       char *rest, *name, ch;
+
+       DEBUG_ENTER;
+
+       parent_ino = ino = xfs.rootino;
+       link_count = 0;
+       for (;;) {
+               di_read (ino);
+               di_size = le64 (icore.di_size);
+               di_mode = le16 (icore.di_mode);
+
+               DEBUG_F("di_mode: %o\n", di_mode);
+               if ((di_mode & IFMT) == IFLNK) {
+                       if (++link_count > MAX_LINK_COUNT) {
+                               errnum = FILE_ERR_SYMLINK_LOOP;
+                               DEBUG_LEAVE(FILE_ERR_SYMLINK_LOOP);
+                               return 0;
+                       }
+                       if (di_size < xfs.bsize - 1) {
+                               xfs_file->pos = 0;
+                               xfs_file->len = di_size;
+                               n = xfs_read_data (linkbuf, xfs_file->len);
+                       } else {
+                               errnum = FILE_ERR_LENGTH;
+                               DEBUG_LEAVE(FILE_ERR_LENGTH);
+                               return 0;
+                       }
+
+                       ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino;
+                       while (n < (xfs.bsize - 1) && (linkbuf[n++] = *dirname++));
+                       linkbuf[n] = 0;
+                       dirname = linkbuf;
+                       continue;
+               }
+
+               DEBUG_F("*dirname: %s\n", dirname);
+               if (!*dirname || isspace (*dirname)) {
+                       if ((di_mode & IFMT) != IFREG) {
+                               errnum = FILE_ERR_BAD_TYPE;
+                               DEBUG_LEAVE(FILE_ERR_BAD_TYPE);
+                               return 0;
+                       }
+                       xfs_file->pos = 0;
+                       xfs_file->len = di_size;
+                       DEBUG_LEAVE(1);
+                       return 1;
+               }
+
+               if ((di_mode & IFMT) != IFDIR) {
+                       errnum = FILE_ERR_NOTDIR;
+                       DEBUG_LEAVE(FILE_ERR_NOTDIR);
+                       return 0;
+               }
+
+               for (; *dirname == '/'; dirname++);
+
+               for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+               *rest = 0;
+
+               name = first_dentry (&new_ino);
+               for (;;) {
+                       cmp = (!*dirname) ? -1 : strcmp(dirname, name);
+                       if (cmp == 0) {
+                               parent_ino = ino;
+                               if (new_ino)
+                                       ino = new_ino;
+                               *(dirname = rest) = ch;
+                               break;
+                       }
+                       name = next_dentry (&new_ino);
+                       if (name == NULL) {
+                               errnum = FILE_ERR_NOTFOUND;
+                               DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+                               *rest = ch;
+                               return 0;
+                       }
+               }
+       }
+}
+
+/* 
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/second/gui/colormap.c b/second/gui/colormap.c
deleted file mode 100644 (file)
index 1317d46..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* 256 color mode color table for Linux, partially borrowed from BootX */
-
-
-unsigned char color_table_red[] = {
-  0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA,
-  0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x02, 0x9E, 0xE9, 0xC4, 0x50, 0xC9, 0xC4, 0xE9,
-  0x65, 0xE3, 0xC2, 0x25, 0xA4, 0xEC, 0x90, 0xA6,
-  0xC4, 0x6A, 0xD1, 0xF3, 0x12, 0xED, 0xA0, 0xC2,
-  0xB8, 0xD5, 0xDB, 0xD2, 0x3E, 0x16, 0xEB, 0x54,
-  0xA9, 0xCD, 0xF5, 0x0A, 0xBA, 0xB3, 0xDC, 0x74,
-  0xCE, 0xF6, 0xD3, 0xC5, 0xEA, 0xB8, 0xED, 0x5E,
-  0xE5, 0x26, 0xF4, 0xA9, 0x82, 0x94, 0xE6, 0x38,
-  0xF2, 0x0F, 0x7F, 0x49, 0xE5, 0xF4, 0xD3, 0xC3,
-  0xC2, 0x1E, 0xD5, 0xC6, 0xA4, 0xFA, 0x0A, 0xBA,
-  0xD4, 0xEB, 0xEA, 0xEC, 0xA8, 0xBC, 0xB4, 0xDC,
-  0x84, 0xE4, 0xCE, 0xEC, 0x92, 0xCD, 0xDC, 0x8B,
-  0xCC, 0x1E, 0xF6, 0xB2, 0x60, 0x2A, 0x96, 0x52,
-  0x0F, 0xBD, 0xFA, 0xCC, 0xB8, 0x7A, 0x4C, 0xD2,
-  0x06, 0xEF, 0x44, 0x64, 0xF4, 0xBA, 0xCE, 0xE6,
-  0x8A, 0x6F, 0x3C, 0x70, 0x7C, 0x9C, 0xBA, 0xDF,
-  0x2C, 0x4D, 0x3B, 0xCA, 0xDE, 0xCE, 0xEE, 0x46,
-  0x6A, 0xAC, 0x96, 0xE5, 0x96, 0x7A, 0xBA, 0xB6,
-  0xE2, 0x7E, 0xAA, 0xC5, 0x96, 0x9E, 0xC2, 0xAA,
-  0xDA, 0x35, 0xB6, 0x82, 0x88, 0xBE, 0xC2, 0x9E,
-  0xB4, 0xD5, 0xDA, 0x9C, 0xA0, 0xD0, 0xA8, 0xC7,
-  0x72, 0xF2, 0xDB, 0x76, 0xDC, 0xBE, 0xAA, 0xF4,
-  0x87, 0x2F, 0x53, 0x8E, 0x36, 0xCE, 0xE6, 0xCA,
-  0xCB, 0xE4, 0xD6, 0xAA, 0x42, 0x5D, 0xB4, 0x59,
-  0x1C, 0xC8, 0x96, 0x6C, 0xDA, 0xCE, 0xE6, 0xCB,
-  0x96, 0x16, 0xFA, 0xBE, 0xAE, 0xFE, 0x6E, 0xD6,
-  0xCE, 0xB6, 0xE5, 0xED, 0xDB, 0xDC, 0xF4, 0x72,
-  0x1F, 0xAE, 0xE6, 0xC2, 0xCA, 0xC4, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-unsigned char color_table_green[] = {
-  0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
-  0x55, 0x55, 0xFF, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x02, 0x88, 0xC4, 0x85, 0x44, 0xA2, 0xA8, 0xE5,
-  0x65, 0xA6, 0xC2, 0x24, 0xA4, 0xB4, 0x62, 0x86,
-  0x94, 0x44, 0xD2, 0xB6, 0x12, 0xD4, 0x73, 0x96,
-  0x92, 0x95, 0xB2, 0xC2, 0x36, 0x0E, 0xBC, 0x54,
-  0x75, 0xA5, 0xF5, 0x0A, 0xB2, 0x83, 0xC2, 0x74,
-  0x9B, 0xBD, 0xA2, 0xCA, 0xDA, 0x8C, 0xCB, 0x42,
-  0xAC, 0x12, 0xDA, 0x7B, 0x54, 0x94, 0xD2, 0x24,
-  0xBE, 0x06, 0x65, 0x33, 0xBB, 0xBC, 0xAB, 0x8C,
-  0x92, 0x1E, 0x9B, 0xB6, 0x6E, 0xFB, 0x04, 0xA2,
-  0xC8, 0xBD, 0xAD, 0xEC, 0x92, 0xBC, 0x7B, 0x9D,
-  0x84, 0xC4, 0xC4, 0xB4, 0x6C, 0x93, 0xA3, 0x5E,
-  0x8D, 0x13, 0xD6, 0x82, 0x4C, 0x2A, 0x7A, 0x5A,
-  0x0D, 0x82, 0xBB, 0xCC, 0x8B, 0x6A, 0x3C, 0xBE,
-  0x06, 0xC4, 0x44, 0x45, 0xDB, 0x96, 0xB6, 0xDE,
-  0x8A, 0x4D, 0x3C, 0x5A, 0x7C, 0x9C, 0xAA, 0xCB,
-  0x1C, 0x4D, 0x2E, 0xB2, 0xBE, 0xAA, 0xDE, 0x3E,
-  0x6A, 0xAC, 0x82, 0xE5, 0x72, 0x62, 0x92, 0x9E,
-  0xCA, 0x4A, 0x8E, 0xBE, 0x86, 0x6B, 0xAA, 0x9A,
-  0xBE, 0x34, 0xAB, 0x76, 0x6E, 0x9A, 0x9E, 0x62,
-  0x76, 0xCE, 0xD3, 0x92, 0x7C, 0xB8, 0x7E, 0xC6,
-  0x5E, 0xE2, 0xC3, 0x54, 0xAA, 0x9E, 0x8A, 0xCA,
-  0x63, 0x2D, 0x3B, 0x8E, 0x1A, 0x9E, 0xC2, 0xA6,
-  0xCB, 0xDC, 0xD6, 0x8E, 0x26, 0x5C, 0xB4, 0x45,
-  0x1C, 0xB8, 0x6E, 0x4C, 0xBC, 0xAE, 0xD6, 0x92,
-  0x63, 0x16, 0xF6, 0x8C, 0x7A, 0xFE, 0x6E, 0xBA,
-  0xC6, 0x86, 0xAA, 0xAE, 0xDB, 0xA4, 0xD4, 0x56,
-  0x0E, 0x6E, 0xB6, 0xB2, 0xBE, 0xBE, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-
-unsigned char color_table_blue[] = {
-  0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA,
-  0x55, 0xFF, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0x04, 0x28, 0x10, 0x0B, 0x14, 0x14, 0x74, 0xC7,
-  0x64, 0x0E, 0xC3, 0x24, 0xA4, 0x0C, 0x10, 0x20,
-  0x0D, 0x04, 0xD1, 0x0D, 0x13, 0x22, 0x0A, 0x40,
-  0x14, 0x0C, 0x11, 0x94, 0x0C, 0x08, 0x0B, 0x56,
-  0x09, 0x47, 0xF4, 0x0B, 0x9C, 0x07, 0x54, 0x74,
-  0x0F, 0x0C, 0x0F, 0xC7, 0x6C, 0x14, 0x14, 0x11,
-  0x0B, 0x04, 0x12, 0x0C, 0x05, 0x94, 0x94, 0x0A,
-  0x34, 0x09, 0x14, 0x08, 0x2F, 0x15, 0x19, 0x11,
-  0x28, 0x0C, 0x0B, 0x94, 0x08, 0xFA, 0x08, 0x7C,
-  0xBC, 0x15, 0x0A, 0xEC, 0x64, 0xBB, 0x0A, 0x0C,
-  0x84, 0x2C, 0xA0, 0x15, 0x10, 0x0D, 0x0B, 0x0E,
-  0x0A, 0x07, 0x10, 0x3C, 0x24, 0x2C, 0x28, 0x5C,
-  0x0A, 0x0D, 0x0A, 0xC1, 0x22, 0x4C, 0x10, 0x94,
-  0x04, 0x0F, 0x45, 0x08, 0x31, 0x54, 0x3C, 0xBC,
-  0x8C, 0x09, 0x3C, 0x18, 0x7C, 0x9C, 0x7C, 0x91,
-  0x0C, 0x4D, 0x17, 0x74, 0x0C, 0x48, 0x9C, 0x3C,
-  0x6A, 0xAC, 0x5C, 0xE3, 0x29, 0x3C, 0x2C, 0x7C,
-  0x6C, 0x04, 0x14, 0xA9, 0x74, 0x07, 0x2C, 0x74,
-  0x4C, 0x34, 0x97, 0x5C, 0x38, 0x0C, 0x5C, 0x04,
-  0x0C, 0xBA, 0xBC, 0x78, 0x18, 0x88, 0x24, 0xC2,
-  0x3C, 0xB4, 0x87, 0x0C, 0x14, 0x4C, 0x3C, 0x10,
-  0x17, 0x2C, 0x0A, 0x8C, 0x04, 0x1C, 0x44, 0x2C,
-  0xCD, 0xD8, 0xD4, 0x34, 0x0C, 0x5B, 0xB4, 0x1E,
-  0x1D, 0xAC, 0x24, 0x18, 0x20, 0x5C, 0xB4, 0x1C,
-  0x09, 0x14, 0xFC, 0x0C, 0x10, 0xFC, 0x6C, 0x7C,
-  0xB4, 0x1C, 0x15, 0x17, 0xDB, 0x18, 0x21, 0x24,
-  0x04, 0x04, 0x44, 0x8C, 0x8C, 0xB7, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
diff --git a/second/gui/effects.c b/second/gui/effects.c
deleted file mode 100644 (file)
index afcd374..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* effects.c */
-/* Adds splash screen and status bar effects for graphical yaboot */
-
-#include "file.h"
-#include "yaboot.h"
-#include "stdlib.h"
-
-#define SB_XSTART  170
-#define SB_XEND    472
-#define SB_YSTART  402
-
-unsigned char bar_grad[] = { 228, 237, 246, 254, 207, 254, 246, 237, 228, 206 };
-
-int scrOpen(void);
-void scrSetEntireColorMap(unsigned char *);
-void scrClear(unsigned char);
-void pcxDisplay(unsigned char *, unsigned int);
-void scrFadeColorMap(unsigned char *, unsigned char *, int);
-unsigned char *pcxColormap(unsigned char *, int);
-void scrPutPixel(int, int, unsigned char);
-
-void fxDisplaySplash(struct boot_fspec_t *filespec)
-{
-  void              *gfx_file;
-  int                gfx_len;
-  unsigned char     *grey_map;
-  int                start_time;
-  struct boot_file_t file;
-  int                result;
-  static int         been_here = 0;
-
-  if(!been_here)
-  {
-     been_here = 1;
-     gfx_file = (void *) malloc(1024 * 512);
-     if (gfx_file == NULL) {
-       prom_printf("malloc failed in fxDisplaySplash()\n");
-       return;
-     }
-
-     scrOpen();
-
-     result = open_file(filespec, &file);
-
-     if(result != FILE_ERR_OK)
-     {
-        prom_printf("Error loading splash screen\n");
-        return;
-     }
-
-     gfx_len = file.fs->read(&file, 1024 * 512 - 765, gfx_file);
-     file.fs->close(&file);
-     grey_map = gfx_file + gfx_len;
-     memset(grey_map, 0/*128*/, 765);
-  }
-
-  scrSetEntireColorMap(grey_map);
-  scrClear(0);
-
-  start_time = prom_getms();
-  while(prom_getms() < start_time + 2000);
-
-  pcxDisplay(gfx_file, gfx_len);
-  scrFadeColorMap(grey_map, pcxColormap( gfx_file, gfx_len ), 2);
-}
-
-
-void fxUpdateSB(unsigned number, unsigned total)
-{
-  int x, y;
-
-  for(x = SB_XSTART; x < SB_XSTART + (SB_XEND - SB_XSTART) * number / total; ++x)
-  {
-     for(y = 0; y < 10; ++y)
-        scrPutPixel(x, SB_YSTART + y, bar_grad[y]);
-  }
-}
-
-
-#define BLOCK_INDEX (1024 * 64)
-
-int fxReadImage(struct boot_file_t *file, unsigned int filesize, void *base)
-{
-  unsigned int count, result = 0;
-
-  for(count = 0; count < filesize; count += result)
-  {
-     result = ((filesize - count) < BLOCK_INDEX) ? (filesize - count) : BLOCK_INDEX;
-     if ((result = file->fs->read(file, result, base + count)) != BLOCK_INDEX)
-       break;
-     fxUpdateSB(count + result, filesize);
-  }
-  fxUpdateSB(count + result, filesize);
-  return(count + result);
-}
diff --git a/second/gui/pcx.c b/second/gui/pcx.c
deleted file mode 100644 (file)
index 0509777..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Crude PCX file loading and display for 640x480 image at boot */
-
-unsigned char *pcxColormap(unsigned char *gfx_file, int gfx_len)
-{
-  return(gfx_file + gfx_len - 768);
-}
-
-extern void scrPutPixel( int x, int y, unsigned char c );
-
-static void inline do_putpixel(int offset, unsigned char c)
-{
-   scrPutPixel(offset % 640, offset / 640, c);
-}
-
-void pcxDisplay(unsigned char *gfx_file, unsigned gfx_len)
-{
-  int offset, file_offset, i, c, f;
-
-  for(offset = 0, file_offset = 128; offset < 640 * 480 && file_offset < gfx_len - 769; file_offset++)
-  {
-     if(((c = gfx_file[file_offset]) & 0xc0) == 0xc0)
-     {
-        f = gfx_file[++file_offset];
-        c &= 0x3f;
-        for(i = 0; i < c; ++i)
-           do_putpixel(offset++, f);
-     }
-     else
-        do_putpixel(offset++, c);
-  }
-}
diff --git a/second/gui/video.c b/second/gui/video.c
deleted file mode 100644 (file)
index b3bd572..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "prom.h"
-
-#define WINDOW_X_SIZE 640
-#define WINDOW_Y_SIZE 480
-
-
-static prom_handle videodev;
-static prom_handle videop;
-static int Xres, Yres;
-static int Xstart, Ystart;
-static int rowbytes;
-static int zoom;
-static unsigned char *address;
-
-static int scrSetColorMap( unsigned char color,
-       unsigned char r, unsigned char g, unsigned char b );
-
-
-int scrOpen()
-{
-  int result = 0;
-  videodev = (prom_handle)call_prom( "open", 1, 1, "screen" );
-  if( videodev == PROM_INVALID_HANDLE )
-     return(-1);
-  videop = (prom_handle)call_prom( "instance-to-package", 1, 1, videodev );
-  if( videop == PROM_INVALID_HANDLE )
-     return(-1);
-
-  result |= prom_getprop(videop, "width", &Xres, 4 );
-  result |= prom_getprop(videop, "height", &Yres, 4 );
-  result |= prom_getprop(videop, "address", &address, 4 );
-  result |= prom_getprop(videop, "linebytes", &rowbytes, 4 );
-
-  prom_map (address, address, rowbytes * Xres);
-
-#if DEBUG
-  prom_printf("width     : %d\n", Xres);
-  prom_printf("height    : %d\n", Yres);
-  prom_printf("address   : 0x%08lx\n", address);
-  prom_printf("linebytes : %d\n", rowbytes);
-  prom_printf("result    : %d\n", result);
-#endif
-  if( result < 0 )
-     return( -1 );
-
-  zoom = Xres / WINDOW_X_SIZE > Yres / WINDOW_Y_SIZE ? Yres / WINDOW_Y_SIZE : Xres / WINDOW_X_SIZE;
-
-  Xstart = Xres / 2 - WINDOW_X_SIZE / 2 * zoom;
-  Ystart = Yres / 2 - WINDOW_Y_SIZE / 2 * zoom;
-
-#if DEBUG
-  prom_printf("zoom      : %d\n", zoom);
-  prom_printf("Xstart    : %d\n", Xstart);
-  prom_printf("Ystart    : %d\n", Ystart);
-#endif
-
-  return( 0 );
-}
-
-
-void scrClear( unsigned char c )
-{
-  int x, y;
-
-  for (y = 0; y < Yres; y++)
-       for (x = 0; x < Xres; x++)
-               address[y * rowbytes + x] = c;
-}
-
-
-void scrClose()
-{
-  call_prom( "close", 1, 0, videodev );
-  videodev = 0;
-}
-
-
-void scrReset()
-{
-  int c;
-  extern unsigned char color_table_red[],
-                       color_table_green[],
-                       color_table_blue[];
-
-  for( c = 0; c < 16; ++c )
-     scrSetColorMap( c, color_table_red[c],
-                        color_table_green[c],
-                        color_table_blue[c] );
-//  scrClose();
-}
-
-static void inline do_pix( int x, int y, unsigned char c )
-{
-  address[ y * rowbytes + x ] = c;
-}
-
-
-void scrPutPixel( int x, int y, unsigned char c )
-{
-  int zx, zy;
-
-  for( zy = 0; zy < zoom; ++zy )
-     for( zx = 0; zx < zoom; ++zx )
-        do_pix( x * zoom + zx + Xstart, y * zoom + zy + Ystart, c );
-}
-
-
-int scrSetColorMap( unsigned char color, unsigned char r, unsigned char g, unsigned char b )
-{
-  int result;
-
-  result = (int)call_prom( "call-method", 6, 1, "color!", videodev, color, b, g, r );
-
-  return( result );
-}
-
-
-void scrFillColorMap( unsigned char r, unsigned char g, unsigned char b )
-{
-  int c;
-
-  for( c = 0; c < 256; ++c )
-     scrSetColorMap( c, r, g, b );
-}
-
-
-void scrSetEntireColorMap( unsigned char *map )
-{
-  int c;
-
-  for( c = 0; c < 256; ++c )
-     scrSetColorMap( c, map[c * 3], map[c * 3 + 1], map[c * 3 + 2] );
-}
-
-
-void scrFadeColorMap( unsigned char *first, unsigned char *last, int rate )
-{
-  int inc, c;
-
-  for( inc = 0; inc < 256; inc += rate )
-     for( c = 0; c < 256; ++c )
-        scrSetColorMap( c, first[c * 3 + 0] * (255 - inc) / 255 + last[c * 3 + 0] * inc / 255,
-                           first[c * 3 + 1] * (255 - inc) / 255 + last[c * 3 + 1] * inc / 255,
-                           first[c * 3 + 2] * (255 - inc) / 255 + last[c * 3 + 2] * inc / 255 );
-}
index aa04c8696d197c4edc535789aebf22dd8ca3da69..39f23ca1083e108384b187bc8d87435e7af4b844 100644 (file)
@@ -223,7 +223,7 @@ partitions_lookup(const char *device)
        if (prom_blksize <= 1)
                prom_blksize = 512;
        if (prom_blksize > MAX_BLOCK_SIZE) {
-               prom_printf("block_size %d not supported !\n");
+               prom_printf("block_size %d not supported !\n", prom_blksize);
                goto bail;
        }
        
@@ -246,7 +246,7 @@ partitions_lookup(const char *device)
                                prom_blksize);
                prom_printf("ISO9660 disk\n");
        } else {
-               prom_printf("Not a macintosh-formatted disk !\n");
+               prom_printf("No supported partition table detected\n");
                goto bail;
        }
 
index 153020d63da2b6589ae84ffeefa350204b8337c5..cd12279c7d413ee32d2c4b90de8a96c4d4653fcf 100644 (file)
@@ -29,6 +29,7 @@
 #include "types.h"
 #include "ctype.h"
 #include "asm/processor.h"
+#include "errors.h"
 
 #define READ_BLOCKS_USE_READ   1
 
@@ -124,7 +125,7 @@ call_method_1 (char *method, prom_handle h, int nargs, ...)
 
   if (prom_args.args[2+nargs] != 0)
     {
-      prom_printf ("method '%s' failed %d\n", method, prom_args.args[2+nargs]);
+      prom_printf ("method '%s' failed %p\n", method, prom_args.args[2+nargs]);
       return 0;
     }
   return prom_args.args[2+nargs+1];
@@ -384,7 +385,7 @@ prom_puts (prom_handle file, char *s)
 void
 prom_vfprintf (prom_handle file, char *fmt, va_list ap)
 {
-  static char printf_buf[1024];
+  static char printf_buf[1536];
   vsprintf (printf_buf, fmt, ap);
   prom_puts (file, printf_buf);
 }
@@ -392,7 +393,7 @@ prom_vfprintf (prom_handle file, char *fmt, va_list ap)
 void
 prom_vprintf (char *fmt, va_list ap)
 {
-  static char printf_buf[1024];
+  static char printf_buf[1536];
   vsprintf (printf_buf, fmt, ap);
   prom_puts (prom_stdout, printf_buf);
 }
@@ -415,6 +416,37 @@ prom_printf (char *fmt, ...)
   va_end (ap);
 }
 
+void
+prom_perror (int error, char *filename)
+{
+     if (error == FILE_ERR_EOF)
+         prom_printf("%s: Unexpected End Of File\n", filename);
+     else if (error == FILE_ERR_NOTFOUND)
+         prom_printf("%s: No such file or directory\n", filename);
+     else if (error == FILE_CANT_SEEK)
+         prom_printf("%s: Seek error\n", filename);
+     else if (error == FILE_IOERR)
+         prom_printf("%s: Input/output error\n", filename);
+     else if (error == FILE_BAD_PATH)
+         prom_printf("%s: Path too long\n", filename); 
+     else if (error == FILE_ERR_BAD_TYPE)
+         prom_printf("%s: Not a regular file\n", filename);
+     else if (error == FILE_ERR_NOTDIR)
+         prom_printf("%s: Not a directory\n", filename);
+     else if (error == FILE_ERR_BAD_FSYS)
+         prom_printf("%s: Unknown or corrupt filesystem\n", filename);
+     else if (error == FILE_ERR_SYMLINK_LOOP)
+         prom_printf("%s: Too many levels of symbolic links\n", filename);
+     else if (error == FILE_ERR_LENGTH)
+         prom_printf("%s: File too large\n", filename);
+     else if (error == FILE_ERR_FSBUSY)
+         prom_printf("%s: Filesystem busy\n", filename);
+     else if (error == FILE_ERR_BADDEV)
+         prom_printf("%s: Unable to open file, Invalid device\n", filename);
+     else
+         prom_printf("%s: Unknown error\n", filename);
+}
+
 void
 prom_readline (char *prompt, char *buf, int len)
 {
@@ -473,6 +505,14 @@ prom_abort (char *fmt, ...)
   prom_exit ();
 }
 
+void
+prom_sleep (int seconds)
+{
+     int end;
+     end = (prom_getms() + (seconds * 1000));
+     while (prom_getms() <= end);
+}
+
 void *
 prom_claim (void *virt, unsigned int size, unsigned int align)
 {
index 5925d0737a037c600b87e3930a3ffa682449cb2f..4bb67e29337b568cd173d7ec1fbb9bca84ead38f 100644 (file)
@@ -40,6 +40,7 @@ sys
 #include "stdlib.h"
 #include "prom.h"
 #include "file.h"
+#include "errors.h"
 #include "cfg.h"
 #include "cmdline.h"
 #include "yaboot.h"
@@ -49,10 +50,6 @@ sys
 #define CONFIG_FILE_NAME       "yaboot.conf"
 #define CONFIG_FILE_MAX                0x8000          /* 32k */
 
-#ifdef CONFIG_SPLASH_SCREEN
-#include "gui.h"
-#endif /* CONFIG_SPLASH_SCREEN */
-
 #ifdef USE_MD5_PASSWORDS
 #include "md5.h"
 #endif /* USE_MD5_PASSWORDS */
@@ -107,9 +104,10 @@ static void     setup_display(void);
 
 int useconf = 0;
 char bootdevice[1024];
-char *bootpath = NULL;
+//char *bootpath = NULL;
 char *password = NULL;
-int bootpartition = -1;
+//int bootpartition = -1;
+struct boot_fspec_t boot;
 int _machine = _MACH_Pmac;
 
 #ifdef CONFIG_COLOR_TEXT
@@ -191,25 +189,22 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
        /* Allocate some memory for malloc'ator */
        malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0);
        if (malloc_base == (void *)-1) {
-               prom_printf("Can't claim malloc buffer (%d bytes at 0x%08lx)\n",
+               prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n",
                        MALLOCSIZE, MALLOCADDR);
                return -1;
        }
        malloc_init(malloc_base, MALLOCSIZE);
-#if DEBUG
-       prom_printf("Malloc buffer allocated at 0x%x (%d bytes)\n",
+       DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n",
                malloc_base, MALLOCSIZE);
-#endif
                
-       /* A few useless printf's */
-#if DEBUG
-       prom_printf("reloc_offset :  %ld         (should be 0)\n", reloc_offset());
-       prom_printf("test_bss     :  %d         (should be 0)\n", test_bss);
-       prom_printf("test_data    :  %d         (should be 0)\n", test_data);
-       prom_printf("&test_data   :  0x%08lx\n", &test_data);
-       prom_printf("&test_bss    :  0x%08lx\n", &test_bss);
-       prom_printf("linked at    :  0x%08lx\n", TEXTADDR);
-#endif 
+       /* A few useless DEBUG_F's */
+       DEBUG_F("reloc_offset :  %ld         (should be 0)\n", reloc_offset());
+       DEBUG_F("test_bss     :  %d         (should be 0)\n", test_bss);
+       DEBUG_F("test_data    :  %d         (should be 0)\n", test_data);
+       DEBUG_F("&test_data   :  %p\n", &test_data);
+       DEBUG_F("&test_bss    :  %p\n", &test_bss);
+       DEBUG_F("linked at    :  0x%08x\n", TEXTADDR);
+
        /* ask the OF info if we're a chrp or pmac */
        /* we need to set _machine before calling finish_device_tree */
        root = prom_finddevice("/");
@@ -225,9 +220,8 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
                }
        }
        
-#if DEBUG
-       prom_printf("Running on _machine = %d\n", _machine);
-#endif
+       DEBUG_F("Running on _machine = %d\n", _machine);
+       DEBUG_SLEEP;
 
        /* Call out main */
        result = yaboot_main();
@@ -235,12 +229,9 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
        /* Get rid of malloc pool */
        malloc_dispose();
        prom_release(malloc_base, MALLOCSIZE);
-#if DEBUG
-       prom_printf("Malloc buffer released. Exiting with code %d\n",
+       DEBUG_F("Malloc buffer released. Exiting with code %d\n",
                result);
 
-#endif
-
        /* Return to OF */
        prom_exit();
        
@@ -324,9 +315,7 @@ load_config_file(char *device, char* path, int partition)
        goto bail;
     }
 
-#if DEBUG
-    prom_printf("Config file successfully parsed\n", sz);
-#endif
+    DEBUG_F("Config file successfully parsed, %d bytes\n", sz);
 
     /* Now, we do the initialisations stored in the config file */
     p = cfg_get_strg(0, "init-code");
@@ -338,9 +327,7 @@ load_config_file(char *device, char* path, int partition)
 #ifdef CONFIG_COLOR_TEXT
     p = cfg_get_strg(0, "fgcolor");
     if (p) {
-#if DEBUG       
-       prom_printf("fgcolor=%s\n", p);
-#endif
+       DEBUG_F("fgcolor=%s\n", p);
        fgcolor = check_color_text_ui(p);
        if (fgcolor == -1) {
          prom_printf("Invalid fgcolor: \"%s\".\n", p);
@@ -348,9 +335,7 @@ load_config_file(char *device, char* path, int partition)
     }
     p = cfg_get_strg(0, "bgcolor");
     if (p) {
-#if DEBUG      
-       prom_printf("bgcolor=%s\n", p);
-#endif
+       DEBUG_F("bgcolor=%s\n", p);
        bgcolor = check_color_text_ui(p);
        if (bgcolor == -1)
          prom_printf("Invalid bgcolor: \"%s\".\n", p);
@@ -361,7 +346,7 @@ load_config_file(char *device, char* path, int partition)
        prom_interpret(temp); 
 #if !DEBUG
        prom_printf("\xc");
-#endif 
+#endif /* !DEBUG */
     }
     if (fgcolor >= 0) {
                char temp[64];
@@ -498,7 +483,7 @@ make_params(char *label, char *params)
 
 void check_password(char *str)
 {
-    int i, end;
+    int i;
 
     for (i = 0; i < 3; i++) {
         prom_printf ("\n%sassword: ", str);
@@ -512,16 +497,15 @@ void check_password(char *str)
         } 
         else if (!strcmp (password, passwdbuff))
            return;
-#else
+#else /* !MD5 */
         if (!strcmp (password, passwdbuff))
            return;
-#endif
+#endif /* USE_MD5_PASSWORDS */
         if (i < 2)
            prom_printf ("Password incorrect. Please try again...");
     }
     prom_printf ("Seems like you don't know the access password.  Go away!\n");
-    end = (prom_getms() + 3000);
-    while (prom_getms() <= end);
+    prom_sleep(3);
     prom_interpret("reset-all");
 }
 
@@ -541,9 +525,6 @@ int get_params(struct boot_param_t* params)
     static char imagepath[1024];
     static char initrdpath[1024];
     static char sysmappath[1024];
-#ifdef CONFIG_SPLASH_SCREEN
-    static char splashpath[1024];
-#endif /* CONFIG_SPLASH_SCREEN */
 
     pause_after = 0;
     memset(params, 0, sizeof(*params));
@@ -551,8 +532,7 @@ int get_params(struct boot_param_t* params)
     params->kernel.part = -1;
     params->rd.part = -1;
     params->sysmap.part = -1;
-    params->splash.part = -1;
-    defpart = bootpartition;
+    defpart = boot.part;
     
     cmdinit();
 
@@ -563,8 +543,7 @@ int get_params(struct boot_param_t* params)
        word_split(&imagename, &params->args);
        timeout = DEFAULT_TIMEOUT;
        if (imagename) {
-            prom_printf("Default supplied on the command line: ");
-            prom_printf("%s ", imagename);
+            prom_printf("Default supplied on the command line: %s ", imagename);
             if (params->args)
                  prom_printf("%s", params->args);
             prom_printf("\n");
@@ -627,7 +606,7 @@ int get_params(struct boot_param_t* params)
        imagename = cfg_get_default();
 
     label = 0;
-    defdevice = bootdevice;
+    defdevice = boot.dev;
 
     if (useconf) {
        defdevice = cfg_get_strg(0, "device");
@@ -647,7 +626,7 @@ int get_params(struct boot_param_t* params)
            label = imagename;
            imagename = p;
            defdevice = cfg_get_strg(label, "device");
-           if(!defdevice) defdevice=bootdevice;
+           if(!defdevice) defdevice=boot.dev;
            p = cfg_get_strg(label, "partition");
            if (p) {
                n = simple_strtol(p, &endp, 10);
@@ -666,6 +645,23 @@ int get_params(struct boot_param_t* params)
        }
     }
 
+    if (!strcmp (imagename, "help")) {
+        prom_printf(
+             "\nPress the tab key for a list of defined images.\n"
+             "The label marked with a \"*\" is is the default image, "
+             "press <return> to boot it.\n\n"
+             "To boot any other label simply type its name and press <return>.\n\n"
+             "To boot a kernel image which is not defined in the yaboot configuration \n"
+             "file, enter the kernel image name as [device:][partno],/path, where \n"
+             "\"device:\" is the OpenFirmware device path to the disk the image \n"
+             "resides on, and \"partno\" is the partition number the image resides on.\n\n"
+             "If you omit \"device:\" and \"partno\" yaboot will use the values of \n"
+             "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n"
+             "device=%s\n"
+             "partition=%d\n\n", defdevice, defpart);
+        return 0;
+    }
+
     if (!strcmp (imagename, "halt")) {
         if (password)
              check_password ("P");
@@ -693,52 +689,36 @@ int get_params(struct boot_param_t* params)
     if (!label && password)
         check_password ("To boot a custom image you must enter the p");
 
-    params->kernel.dev = parse_device_path(imagepath, &params->kernel.file,
-       &params->kernel.part);
-    if (validate_fspec(&params->kernel, defdevice, defpart) != FILE_ERR_OK) {
-       prom_printf(
-"Enter the kernel image name as [device:][partno]/path, where partno is a\n"
-"number from 0 to 16.  Instead of /path you can type [mm-nn] to specify a\n"
-"range of disk blocks (512B)\n"
-"Example: hd:3,/vmlinux\n");
-       return 0;
+    if (!parse_device_path(imagepath, defdevice, defpart,
+                          "/vmlinux", &params->kernel)) {
+        prom_printf("%s: Unable to parse\n", imagepath);
+        return 0;
     }
+    DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev,
+           params->kernel.part, params->kernel.file);
 
     if (useconf) {
        p = cfg_get_strg(label, "initrd");
        if (p && *p) {
-#if DEBUG
-           prom_printf("parsing initrd path <%s>\n", p);
-#endif     
+           DEBUG_F("Parsing initrd path <%s>\n", p);
            strncpy(initrdpath, p, 1024);
-           params->rd.dev = parse_device_path(initrdpath,
-               &params->rd.file, &params->rd.part);
-           validate_fspec(&params->rd, defdevice, defpart);
+           if (!parse_device_path(initrdpath, defdevice, defpart,
+                                  "/root.bin", &params->rd)) {
+                prom_printf("%s: Unable to parse\n", imagepath);
+                return 0;
+           }
        }
        p = cfg_get_strg(label, "sysmap");
        if (p && *p) {
-#if DEBUG
-           prom_printf("parsing sysmap path <%s>\n", p);
-#endif     
+           DEBUG_F("Parsing sysmap path <%s>\n", p);
            strncpy(sysmappath, p, 1024);
-           params->sysmap.dev = parse_device_path(sysmappath,
-               &params->sysmap.file, &params->sysmap.part);
-           validate_fspec(&params->sysmap, defdevice, defpart);
-       }
-#ifdef CONFIG_SPLASH_SCREEN
-       p = cfg_get_strg(label, "splash");
-       if (p && *p) {
-#if DEBUG
-           prom_printf("parsing splash path <%s>\n", p);
-#endif     
-           strncpy(splashpath, p, 1024);
-           params->splash.dev = parse_device_path(splashpath,
-               &params->splash.file, &params->splash.part);
-           validate_fspec(&params->splash, defdevice, defpart);
+           if (!parse_device_path(sysmappath, defdevice, defpart,
+                                  "/boot/System.map", &params->sysmap)) {
+                prom_printf("%s: Unable to parse\n", imagepath);
+                return 0;
+           }
        }
-#endif /* CONFIG_SPLASH_SCREEN */
-   }
-    
+    }
     return 0;
 }
 
@@ -779,121 +759,139 @@ yaboot_text_ui(void)
        if (!params.kernel.file)
            continue;
        
-#ifdef CONFIG_SPLASH_SCREEN
-       if (params.splash.file)
-               fxDisplaySplash(&params.splash);
-#endif /* CONFIG_SPLASH_SCREEN */
        prom_printf("Please wait, loading kernel...\n");
 
-       if(bootpath && !strcmp(bootpath,"\\\\") && params.kernel.file[0] != '/') {
-               loc=(char*)malloc(strlen(params.kernel.file)+3);
-               if (!loc) {
-                       prom_printf ("malloc error\n");
-                       goto next;
-               }
-               strcpy(loc,bootpath);
-               strcat(loc,params.kernel.file);
-               free(params.kernel.file);
-               params.kernel.file=loc;
+       memset(&file, 0, sizeof(file));
+
+       if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/'
+           && params.kernel.file[0] != '\\') {
+            loc=(char*)malloc(strlen(params.kernel.file)+3);
+            if (!loc) {
+                 prom_printf ("malloc error\n");
+                 goto next;
+            }
+            strcpy(loc,boot.file);
+            strcat(loc,params.kernel.file);
+            free(params.kernel.file);
+            params.kernel.file=loc;
        }
         result = open_file(&params.kernel, &file);
         if (result != FILE_ERR_OK) {
-           prom_printf("\nImage not found.... try again\n");
-           goto next;
+            prom_printf("%s:%d,", params.kernel.dev, params.kernel.part);
+            prom_perror(result, params.kernel.file);
+            goto next;
        }
 
        /* Read the Elf e_ident, e_type and e_machine fields to
         * determine Elf file type
         */
         if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
-           prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
-           goto next;
+            prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
+            file.fs->close(&file);
+            memset(&file, 0, sizeof(file));
+            goto next;
        }
 
-       if ( is_elf32(&loadinfo) ) {
-            if ( !load_elf32(&file, &loadinfo) )
-                goto next;
-            prom_printf("   Elf32 kernel loaded...\n");
-       } else if ( is_elf64(&loadinfo) ) {
-            if ( !load_elf64(&file, &loadinfo) )
-                goto next;
-            prom_printf("   Elf64 kernel loaded...\n");
+       if (is_elf32(&loadinfo)) {
+            if (!load_elf32(&file, &loadinfo)) {
+                 file.fs->close(&file);
+                 memset(&file, 0, sizeof(file));
+                 goto next;
+            }
+            prom_printf("   Elf32 kernel loaded...\n");
+       } else if (is_elf64(&loadinfo)) {
+            if (!load_elf64(&file, &loadinfo)) {
+                 file.fs->close(&file);
+                 memset(&file, 0, sizeof(file));
+                 goto next;
+            }
+            prom_printf("   Elf64 kernel loaded...\n");
        } else {
-            prom_printf ("Not a valid ELF image\n");
-            goto next;
+            prom_printf ("%s: Not a valid ELF image\n", params.kernel.file);
+            file.fs->close(&file);
+            memset(&file, 0, sizeof(file));
+            goto next;
        }
         file.fs->close(&file);
+       memset(&file, 0, sizeof(file));
 
        /* If sysmap, load it. 
         */
        if (params.sysmap.file) {
-           prom_printf("Loading System.map ...\n");
-           if(bootpath && !strcmp(bootpath,"\\\\") && params.sysmap.file[0] != '/') {
-                   if (loc) free(loc);
-                   loc=(char*)malloc(strlen(params.sysmap.file)+3);
-                   if (!loc) {
-                           prom_printf ("malloc error\n");
-                           goto next;
-                   }
-                   strcpy(loc,bootpath);
-                   strcat(loc,params.sysmap.file);
-                   free(params.sysmap.file);
-                   params.sysmap.file=loc;
-           }
-
-           result = open_file(&params.sysmap, &file);
-           if (result != FILE_ERR_OK)
-               prom_printf("\nSystem.map file not found.\n");
-           else {
-               sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
-               if (sysmap_base == (void *)-1) {
-                   prom_printf("claim failed for sysmap memory\n");
-                   sysmap_base = 0;
-               } else {
-                   sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
-                   if (sysmap_size == 0)
-                       sysmap_base = 0;
-                   else
-                       ((char *)sysmap_base)[sysmap_size++] = 0;
-               }
-               file.fs->close(&file);
-           }
-           if (sysmap_base) {
-               prom_printf("System.map loaded at 0x%08lx, size: %d Kbytes\n",
-                       sysmap_base, sysmap_size >> 10);
-               loadinfo.memsize += _ALIGN(0x100000, 0x1000);
-           } else {
-               prom_printf("System.map load failed !\n");
-               prom_pause();
-           }
+            prom_printf("Loading System.map ...\n");
+            if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/'
+               && params.sysmap.file[0] != '\\') {
+                 if (loc) free(loc);
+                 loc=(char*)malloc(strlen(params.sysmap.file)+3);
+                 if (!loc) {
+                      prom_printf ("malloc error\n");
+                      goto next;
+                 }
+                 strcpy(loc,boot.file);
+                 strcat(loc,params.sysmap.file);
+                 free(params.sysmap.file);
+                 params.sysmap.file=loc;
+            }
+            
+            result = open_file(&params.sysmap, &file);
+            if (result != FILE_ERR_OK) {
+                 prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
+                 prom_perror(result, params.sysmap.file);
+            }
+            else {
+                 sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
+                 if (sysmap_base == (void *)-1) {
+                      prom_printf("Claim failed for sysmap memory\n");
+                      sysmap_base = 0;
+                 } else {
+                      sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
+                      if (sysmap_size == 0)
+                           sysmap_base = 0;
+                      else
+                           ((char *)sysmap_base)[sysmap_size++] = 0;
+                 }
+                 file.fs->close(&file);
+                 memset(&file, 0, sizeof(file));
+            }
+            if (sysmap_base) {
+                 prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
+                             sysmap_base, sysmap_size >> 10);
+                 loadinfo.memsize += _ALIGN(0x100000, 0x1000);
+            } else {
+                 prom_printf("System.map load failed !\n");
+                 prom_pause();
+            }
        }
 
        /* If ramdisk, load it. For now, we can't tell the size it will be
         * so we claim an arbitrary amount of 4Mb
         */
        if (params.rd.file) {
-           if(bootpath && !strcmp(bootpath,"\\\\") && params.rd.file[0] != '/')
+           if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/'
+              && params.kernel.file[0] != '\\')
            {
                if (loc) free(loc);
                loc=(char*)malloc(strlen(params.rd.file)+3);
                if (!loc) {
-                   prom_printf ("malloc error\n");
+                   prom_printf ("Malloc error\n");
                    goto next;
                }
-               strcpy(loc,bootpath);
+               strcpy(loc,boot.file);
                strcat(loc,params.rd.file);
                free(params.rd.file);
                params.rd.file=loc;
            }
            prom_printf("Loading ramdisk...\n");
            result = open_file(&params.rd, &file);
-           if (result != FILE_ERR_OK)
-               prom_printf("\nRamdisk image not found.\n");
+           if (result != FILE_ERR_OK) {
+                prom_printf("%s:%d,", params.rd.dev, params.rd.part);
+                prom_perror(result, params.rd.file);
+           }
            else {
 #define INITRD_CHUNKSIZE 0x400000
                initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
                if (initrd_base == (void *)-1) {
-                   prom_printf("claim failed for initrd memory\n");
+                   prom_printf("Claim failed for initrd memory\n");
                    initrd_base = 0;
                } else {
                    initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
@@ -905,20 +903,19 @@ yaboot_text_ui(void)
                      initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
                      initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
                      if (initrd_more != initrd_want) {
-                       prom_printf("claim failed for initrd memory at %x rc=%x\n",initrd_want,initrd_more);
+                       prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
                        break;
                      }
                    initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
-#if DEBUG
-                   prom_printf("  block at %x rc=%x\n",initrd_more,initrd_read);
-#endif
+                   DEBUG_F("  block at %p rc=%lu\n",initrd_more,initrd_read);
                    initrd_size += initrd_read;
                    }
                }
                file.fs->close(&file);
+               memset(&file, 0, sizeof(file));
            }
            if (initrd_base)
-               prom_printf("ramdisk loaded at 0x%08lx, size: %d Kbytes\n",
+               prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
                        initrd_base, initrd_size >> 10);
            else {
                prom_printf("ramdisk load failed !\n");
@@ -926,17 +923,11 @@ yaboot_text_ui(void)
            }
        }
 
-#if DEBUG
-       prom_printf("setting kernel args to: %s\n", params.args);
-#endif 
+       DEBUG_F("setting kernel args to: %s\n", params.args);
        prom_setargs(params.args);
-#if DEBUG
-       prom_printf("flushing icache...");
-#endif 
+       DEBUG_F("flushing icache...");
        flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
-#if DEBUG
-       prom_printf(" done\n");
-#endif 
+       DEBUG_F(" done\n");
 
        /* 
         * Fill mew boot infos
@@ -952,14 +943,8 @@ yaboot_text_ui(void)
         * by the malloc pool
         */
        prom_map (birec, birec, 0x10000);
-#if DEBUG
-       prom_printf("birec at 0x%08lx\n", birec);
-       {
-           int i = prom_getms();
-           while((prom_getms() - i) < 2000)
-               ;
-       }
-#endif 
+       DEBUG_F("birec at %p\n", birec);
+       DEBUG_SLEEP;
 
        birec->tag = BI_FIRST;
        birec->size = sizeof(struct bi_record);
@@ -989,26 +974,21 @@ yaboot_text_ui(void)
        /* compute the kernel's entry point. */
        kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
 
-#if DEBUG
-       prom_printf("Kernel entry point = 0x%08lx\n", kernel_entry);
-        prom_printf("kernel: arg1 = 0x%08lx,\n"
-                    "        arg2 = 0x%08lx,\n"
-                    "        prom = 0x%08lx,\n"
-                    "        arg4 = 0x%08lx,\n"
-                    "        arg5 = 0x%08lx\n\n",
+       DEBUG_F("Kernel entry point = %p\n", kernel_entry);
+        DEBUG_F("kernel: arg1 = %p,\n"
+               "        arg2 = 0x%08lx,\n"
+               "        prom = %p,\n"
+               "        arg4 = %d,\n"
+               "        arg5 = %d\n\n",
                 initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
 
-#endif 
+       DEBUG_F("Entering kernel...\n");
 
-#if DEBUG
-       prom_printf("entering kernel...\n");
-#endif
         /* call the kernel with our stack. */
         kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
         continue;
 next:
-        if( file.fs != NULL )
-            file.fs->close(&file);    
+       ; /* do nothing */
     }
 }
 
@@ -1027,30 +1007,28 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
        return 0;
     }
 
-#if DEBUG
-    prom_printf("Elf32 header:\n");
-    prom_printf(" e.e_type      = %d\n", (int)e->e_type);
-    prom_printf(" e.e_machine   = %d\n", (int)e->e_machine);
-    prom_printf(" e.e_version   = %d\n", (int)e->e_version);
-    prom_printf(" e.e_entry     = 0x%08x\n", (int)e->e_entry);
-    prom_printf(" e.e_phoff     = 0x%08x\n", (int)e->e_phoff);
-    prom_printf(" e.e_shoff     = 0x%08x\n", (int)e->e_shoff);
-    prom_printf(" e.e_flags     = %d\n", (int)e->e_flags);
-    prom_printf(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
-    prom_printf(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
-    prom_printf(" e.e_phnum     = %d\n", (int)e->e_phnum);
-#endif     
+    DEBUG_F("Elf32 header:\n");
+    DEBUG_F(" e.e_type      = %d\n", (int)e->e_type);
+    DEBUG_F(" e.e_machine   = %d\n", (int)e->e_machine);
+    DEBUG_F(" e.e_version   = %d\n", (int)e->e_version);
+    DEBUG_F(" e.e_entry     = 0x%08x\n", (int)e->e_entry);
+    DEBUG_F(" e.e_phoff     = 0x%08x\n", (int)e->e_phoff);
+    DEBUG_F(" e.e_shoff     = 0x%08x\n", (int)e->e_shoff);
+    DEBUG_F(" e.e_flags     = %d\n", (int)e->e_flags);
+    DEBUG_F(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
+    DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+    DEBUG_F(" e.e_phnum     = %d\n", (int)e->e_phnum);
 
     loadinfo->entry = e->e_entry;
 
     if (e->e_phnum > MAX_HEADERS) {
-       prom_printf ("can only load kernels with one program header\n");
+       prom_printf ("Can only load kernels with one program header\n");
        return 0;
     }
 
     ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
     if (!ph) {
-       prom_printf ("malloc error\n");
+       prom_printf ("Malloc error\n");
        return 0;
     }
 
@@ -1095,29 +1073,26 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
     /* leave some room (1Mb) for boot infos */
     loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
     /* Claim OF memory */
-#if DEBUG
-    prom_printf("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
-#endif    
+    DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
 
     /* On some systems, loadaddr may already be claimed, so try some
      * other nearby addresses before giving up.
      */
-    loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32) ? KERNELADDR : e->e_entry;
+    loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32 ||
+               e->e_entry == 0) ? KERNELADDR : e->e_entry;
     for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
        loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
        if (loadinfo->base != (void *)-1) break;
     }
     if (loadinfo->base == (void *)-1) {
-       prom_printf("claim error, can't allocate kernel memory\n");
+       prom_printf("Claim error, can't allocate kernel memory\n");
        return 0;
     }  
 
-#if DEBUG
-    prom_printf("After ELF parsing, load base: 0x%08lx, mem_sz: 0x%08lx\n",
+    DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
            loadinfo->base, loadinfo->memsize);
-    prom_printf("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+    DEBUG_F("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
            loadaddr, loadinfo->memsize);
-#endif    
 
     /* Load the program segments... */
     p = ph;
@@ -1128,27 +1103,18 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
 
            /* Now, we skip to the image itself */
            if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
-                   prom_printf ("seek error\n");
+                   prom_printf ("Seek error\n");
                    prom_release(loadinfo->base, loadinfo->memsize);
                    return 0;
            }
            offset = p->p_vaddr - loadinfo->load_loc;
-#ifdef CONFIG_SPLASH_SCREEN
-           if (fxReadImage(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
-#else /* CONFIG_SPLASH_SCREEN */
            if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
-#endif /* CONFIG_SPLASH_SCREEN */
-                   prom_printf ("read failed\n");
-                   prom_release(loadinfo->base, loadinfo->memsize);
-                   return 0;
+                prom_printf ("Read failed\n");
+                prom_release(loadinfo->base, loadinfo->memsize);
+                return 0;
            }
     }
 
-#if 0  /* to make editor happy */
-    }
-#endif 
-    (*(file->fs->close))(file);
-
     free(ph);
     
     /* Return success at loading the Elf32 kernel */
@@ -1170,41 +1136,39 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
        return 0;
     }
 
-#if DEBUG
-    prom_printf("Elf64 header:\n");
-    prom_printf(" e.e_type      = %d\n", (int)e->e_type);
-    prom_printf(" e.e_machine   = %d\n", (int)e->e_machine);
-    prom_printf(" e.e_version   = %d\n", (int)e->e_version);
-    prom_printf(" e.e_entry     = 0x%016lx\n", (long)e->e_entry);
-    prom_printf(" e.e_phoff     = 0x%016lx\n", (long)e->e_phoff);
-    prom_printf(" e.e_shoff     = 0x%016lx\n", (long)e->e_shoff);
-    prom_printf(" e.e_flags     = %d\n", (int)e->e_flags);
-    prom_printf(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
-    prom_printf(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
-    prom_printf(" e.e_phnum     = %d\n", (int)e->e_phnum);
-#endif     
+    DEBUG_F("Elf64 header:\n");
+    DEBUG_F(" e.e_type      = %d\n", (int)e->e_type);
+    DEBUG_F(" e.e_machine   = %d\n", (int)e->e_machine);
+    DEBUG_F(" e.e_version   = %d\n", (int)e->e_version);
+    DEBUG_F(" e.e_entry     = 0x%016lx\n", (long)e->e_entry);
+    DEBUG_F(" e.e_phoff     = 0x%016lx\n", (long)e->e_phoff);
+    DEBUG_F(" e.e_shoff     = 0x%016lx\n", (long)e->e_shoff);
+    DEBUG_F(" e.e_flags     = %d\n", (int)e->e_flags);
+    DEBUG_F(" e.e_ehsize    = 0x%08x\n", (int)e->e_ehsize);
+    DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+    DEBUG_F(" e.e_phnum     = %d\n", (int)e->e_phnum);
 
     loadinfo->entry = e->e_entry;
 
     if (e->e_phnum > MAX_HEADERS) {
-       prom_printf ("can only load kernels with one program header\n");
+       prom_printf ("Can only load kernels with one program header\n");
        return 0;
     }
 
     ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
     if (!ph) {
-       prom_printf ("malloc error\n");
+       prom_printf ("Malloc error\n");
        return 0;
     }
 
     /* Now, we read the section header */
     if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
-       prom_printf ("seek error\n");
+       prom_printf ("Seek error\n");
        return 0;
     }
     if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
            sizeof(Elf64_Phdr) * e->e_phnum) {
-       prom_printf ("read error\n");
+       prom_printf ("Read error\n");
        return 0;
     }
 
@@ -1238,9 +1202,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
     /* leave some room (1Mb) for boot infos */
     loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
     /* Claim OF memory */
-#if DEBUG
-    prom_printf("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
-#endif    
+    DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
 
     /* On some systems, loadaddr may already be claimed, so try some
      * other nearby addresses before giving up.
@@ -1251,16 +1213,14 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
        if (loadinfo->base != (void *)-1) break;
     }
     if (loadinfo->base == (void *)-1) {
-       prom_printf("claim error, can't allocate kernel memory\n");
+       prom_printf("Claim error, can't allocate kernel memory\n");
        return 0;
     }  
 
-#if DEBUG
-    prom_printf("After ELF parsing, load base: 0x%08lx, mem_sz: 0x%08lx\n",
+    DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
            loadinfo->base, loadinfo->memsize);
-    prom_printf("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+    DEBUG_F("    wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
            loadaddr, loadinfo->memsize);
-#endif    
 
     /* Load the program segments... */
     p = ph;
@@ -1271,27 +1231,18 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
 
            /* Now, we skip to the image itself */
            if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
-                   prom_printf ("seek error\n");
+                   prom_printf ("Seek error\n");
                    prom_release(loadinfo->base, loadinfo->memsize);
                    return 0;
            }
            offset = p->p_vaddr - loadinfo->load_loc;
-#ifdef CONFIG_SPLASH_SCREEN
-           if (fxReadImage(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
-#else /* CONFIG_SPLASH_SCREEN */
            if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
-#endif /* CONFIG_SPLASH_SCREEN */
-                   prom_printf ("read failed\n");
+                   prom_printf ("Read failed\n");
                    prom_release(loadinfo->base, loadinfo->memsize);
                    return 0;
            }
     }
 
-#if 0  /* to make editor happy */
-    }
-#endif 
-    (*(file->fs->close))(file);
-
     free(ph);
     
     /* Return success at loading the Elf64 kernel */
@@ -1356,32 +1307,25 @@ setup_display(void)
        /* Try Apple's mac-boot screen ihandle */
        result = (int)call_prom_return("interpret", 1, 2,
                "\" _screen-ihandle\" $find if execute else 0 then", &scrn);
-#if DEBUG
-       prom_printf("trying to get screen ihandle, result: 0x%x, scrn: 0x%x\n", result, scrn);
-#endif         
+       DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn);
+
        if (scrn == 0 || scrn == PROM_INVALID_HANDLE) {
                char type[32];
                /* Hrm... check to see if stdout is a display */
                scrn = call_prom ("instance-to-package", 1, 1, prom_stdout);
-#if DEBUG
-               prom_printf("instance-to-package of stdout is: 0x%x\n", scrn);
-#endif         
+               DEBUG_F("instance-to-package of stdout is: %p\n", scrn);
                if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) {
-#if DEBUG
-                       prom_printf("got it ! stdout is a screen\n");
-#endif         
+                       DEBUG_F("got it ! stdout is a screen\n");
                        scrn = prom_stdout;
                } else {
                        /* Else, we try to open the package */
                        scrn = (prom_handle)call_prom( "open", 1, 1, "screen" );
-#if DEBUG
-                       prom_printf("Open screen result: 0x%x\n", scrn);
-#endif         
+                       DEBUG_F("Open screen result: %p\n", scrn);
                }
        }
        
        if (scrn == PROM_INVALID_HANDLE) {
-               prom_printf("no screen device found !/n");
+               prom_printf("No screen device found !/n");
                return;
        }
        for(i=0;i<16;i++) {
@@ -1403,10 +1347,12 @@ setup_display(void)
                        ansi_color_table[i].name);
        }
        prom_printf("\x1b[1;37m\x1b[2;40m");    
-#endif
+#endif /* COLOR_TEST */
+
 #if !DEBUG
        prom_printf("\xc");
-#endif 
+#endif /* !DEBUG */
+
 #endif /* CONFIG_SET_COLORMAP */
 }
 
@@ -1417,49 +1363,57 @@ yaboot_main(void)
                setup_display();
        
        prom_get_chosen("bootpath", bootdevice, sizeof(bootdevice));
-#if DEBUG
-       prom_printf("/chosen/bootpath = %s\n", bootdevice);
-#endif 
+       DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
        if (bootdevice[0] == 0)
                prom_get_options("boot-device", bootdevice, sizeof(bootdevice));
        if (bootdevice[0] == 0) {
            prom_printf("Couldn't determine boot device\n");
            return -1;
        }
-       parse_device_path(bootdevice, &bootpath, &bootpartition);
-#if DEBUG
-       prom_printf("after parse_device_path: device:%s, path: %s, partition: %d\n",
-               bootdevice, bootpath ? bootpath : NULL, bootpartition);
-#endif 
-       if (bootpath) {
-               if (!strncmp(bootpath, "\\\\", 2))
-                       bootpath[2] = 0;
-               else {
-                       char *p, *last;
-                       p = last = bootpath;
-                       while(*p) {
-                           if (*p == '\\')
-                               last = p;
-                           p++;
-                       }
-                       if (p)
-                               *(last) = 0;
-                       else
-                               bootpath = NULL;
-                       if (bootpath && strlen(bootpath))
-                               strcat(bootpath, "\\");
-               }
+
+       if (!parse_device_path(bootdevice, (_machine == _MACH_Pmac) ? "hd" : "disc",
+                              -1, "", &boot)) {
+            prom_printf("%s: Unable to parse\n", bootdevice);
+            return -1;
        }
-#if DEBUG
-       prom_printf("after path fixup: device:%s, path: %s, partition: %d\n",
-               bootdevice, bootpath ? bootpath : NULL, bootpartition);
-#endif 
-       useconf = load_config_file(bootdevice, bootpath, bootpartition);
+       DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n",
+               boot.dev, boot.part, boot.file);
+
+       if (strlen(boot.file)) {
+            if (!strncmp(boot.file, "\\\\", 2))
+                 boot.file = "\\\\";
+            else {
+                 char *p, *last;
+                 p = last = boot.file;
+                 while(*p) {
+                      if (*p == '\\')
+                           last = p;
+                      p++;
+                 }
+                 if (p)
+                      *(last) = 0;
+                 else
+                      boot.file = "";
+                 if (strlen(boot.file))
+                      strcat(boot.file, "\\");
+            }
+       }
+       DEBUG_F("After path fixup: dev=%s, part=%d, file=%s\n",
+               boot.dev, boot.part, boot.file);
+
+       useconf = load_config_file(boot.dev, boot.file, boot.part);
 
        prom_printf("Welcome to yaboot version " VERSION "\n");
+       prom_printf("Enter \"help\" to get some basic usage information\n");
        
        yaboot_text_ui();
        
        prom_printf("Bye.\n");
        return 0;
 }
+/* 
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
index 4088c32c86743643d3e6c7827876fc6c8d6b5c51..74c8efc8c6801710b8af645ffb444ceb68e644e6 100644 (file)
@@ -153,7 +153,7 @@ main(int ac, char **av)
        exit(0);
 
  notelf:
-       fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+       fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
        exit(1);
 
  nospace:
index 976423c76279a9d193020b47b145a64517901a74..8b8f40238c885f8fae41665aa1c6fbeebecbc282 100755 (executable)
--- a/ybin/ybin
+++ b/ybin/ybin
@@ -28,7 +28,7 @@ if [ -n "$PATH_PREFIX" ] ; then
 fi
 PRG="${0##*/}"
 SIGINT="$PRG: Interrupt caught ... exiting"
-VERSION=1.3.3
+VERSION=1.3.4pre1
 DEBUG=0
 VERBOSE=0
 TMP="${TMPDIR:-/tmp}"