summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2000-12-13 17:53:55 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2000-12-13 17:53:55 +0000
commit0ef748fb45137bac811ded19dfad2034f924505a (patch)
tree781c137a2c5303c3ad851c5982c2641fedc45bbf /cpukit/libfs/src
parent2000-12-13 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-0ef748fb45137bac811ded19dfad2034f924505a.tar.bz2
2000-12-12 Jake Janovetz <janovetz@uiuc.edu>
* src/imfs/linearfile.c, src/imfs/imfs_load_tar.c: New files. * src/imfs/Makefile.am, src/imfs/imfs.h, src/imfs/imfs_creat.c, src/imfs/imfs_debug.c, src/imfs/imfs_eval.c, src/imfs/imfs_handlers_memfile.c, src/imfs/imfs_init.c, src/imfs/imfs_initsupp.c, src/imfs/imfs_stat.c, src/imfs/miniimfs_init.c: Added "tarfs". This is not really a tar filesystem. It is a way to load a tar image into the IMFS but actually leave bulky file contents in the original tar image. It essentially adds the linear file type and associated support and a loader routine.
Diffstat (limited to 'cpukit/libfs/src')
-rw-r--r--cpukit/libfs/src/imfs/Makefile.am4
-rw-r--r--cpukit/libfs/src/imfs/imfs.h29
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c4
-rw-r--r--cpukit/libfs/src/imfs/imfs_debug.c10
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c3
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_memfile.c17
-rw-r--r--cpukit/libfs/src/imfs/imfs_init.c1
-rw-r--r--cpukit/libfs/src/imfs/imfs_initsupp.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_load_tar.c209
-rw-r--r--cpukit/libfs/src/imfs/imfs_stat.c1
-rw-r--r--cpukit/libfs/src/imfs/linearfile.c110
-rw-r--r--cpukit/libfs/src/imfs/miniimfs_init.c1
12 files changed, 390 insertions, 7 deletions
diff --git a/cpukit/libfs/src/imfs/Makefile.am b/cpukit/libfs/src/imfs/Makefile.am
index 420cad28f2..9d401c86d9 100644
--- a/cpukit/libfs/src/imfs/Makefile.am
+++ b/cpukit/libfs/src/imfs/Makefile.am
@@ -11,10 +11,10 @@ IMFS_C_FILES = imfs_chown.c imfs_config.c imfs_creat.c imfs_directory.c \
imfs_eval.c imfs_free.c imfs_fsunmount.c imfs_gtkn.c imfs_init.c \
imfs_initsupp.c imfs_link.c imfs_mknod.c imfs_mount.c imfs_fchmod.c \
imfs_unlink.c imfs_unmount.c imfs_utime.c imfs_ntype.c imfs_stat.c \
- imfs_getchild.c memfile.c deviceio.c imfs_handlers_device.c \
+ imfs_getchild.c memfile.c linearfile.c deviceio.c imfs_handlers_device.c \
imfs_handlers_directory.c imfs_handlers_link.c imfs_handlers_memfile.c \
imfs_debug.c imfs_rmnod.c imfs_symlink.c imfs_readlink.c imfs_fdatasync.c \
- imfs_fcntl.c ioman.c miniimfs_init.c
+ imfs_fcntl.c ioman.c miniimfs_init.c imfs_load_tar.c
UNIX_C_FILES = imfs_unixstub.c
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index 3a44c50ee3..2b2d84806f 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -94,6 +94,11 @@ typedef struct {
block_ptr triply_indirect; /* 128 doubly indirect blocks */
} IMFS_memfile_t;
+typedef struct {
+ off_t size; /* size of file in bytes */
+ block_p direct; /* pointer to file image */
+} IMFS_linearfile_t;
+
/*
* Important block numbers for "memfiles"
*/
@@ -125,8 +130,9 @@ typedef struct {
#define IMFS_HARD_LINK RTEMS_FILESYSTEM_HARD_LINK
#define IMFS_SYM_LINK RTEMS_FILESYSTEM_SYM_LINK
#define IMFS_MEMORY_FILE RTEMS_FILESYSTEM_MEMORY_FILE
+#define IMFS_LINEAR_FILE (RTEMS_FILESYSTEM_MEMORY_FILE + 1)
-#define IMFS_NUMBER_OF_TYPES (IMFS_MEMORY_FILE + 1)
+#define IMFS_NUMBER_OF_TYPES (IMFS_LINEAR_FILE + 1)
typedef union {
IMFS_directory_t directory;
@@ -134,6 +140,7 @@ typedef union {
IMFS_link_t hard_link;
IMFS_sym_link_t sym_link;
IMFS_memfile_t file;
+ IMFS_linearfile_t linearfile;
} IMFS_types_union;
/*
@@ -195,6 +202,7 @@ struct IMFS_jnode_tt {
typedef struct {
ino_t ino_count;
+ rtems_filesystem_file_handlers_r *linearfile_handlers;
rtems_filesystem_file_handlers_r *memfile_handlers;
rtems_filesystem_file_handlers_r *directory_handlers;
} IMFS_fs_info_t;
@@ -226,6 +234,7 @@ typedef enum {
extern rtems_filesystem_file_handlers_r IMFS_directory_handlers;
extern rtems_filesystem_file_handlers_r IMFS_device_handlers;
extern rtems_filesystem_file_handlers_r IMFS_link_handlers;
+extern rtems_filesystem_file_handlers_r IMFS_linearfile_handlers;
extern rtems_filesystem_file_handlers_r IMFS_memfile_handlers;
extern rtems_filesystem_operations_table IMFS_ops;
extern rtems_filesystem_operations_table miniIMFS_ops;
@@ -246,6 +255,7 @@ int miniIMFS_initialize(
int IMFS_initialize_support(
rtems_filesystem_mount_table_entry_t *mt_entry,
rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *linearfile_handlers,
rtems_filesystem_file_handlers_r *memfile_handlers,
rtems_filesystem_file_handlers_r *directory_handlers
);
@@ -254,6 +264,11 @@ int IMFS_fsunmount(
rtems_filesystem_mount_table_entry_t *mt_entry
);
+int rtems_tarfs_mount(
+ char *mountpoint,
+ unsigned char *addr,
+ unsigned long length
+);
/*
* Returns the number of characters copied from path to token.
@@ -398,6 +413,18 @@ int imfs_dir_rmnod(
rtems_filesystem_location_info_t *pathloc /* IN */
);
+int linearfile_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ unsigned32 count /* IN */
+);
+
+int linearfile_lseek(
+ rtems_libio_t *iop, /* IN */
+ off_t offset, /* IN */
+ int whence /* IN */
+);
+
int memfile_open(
rtems_libio_t *iop, /* IN */
const char *pathname, /* IN */
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
index b0934c0463..29c49cc34b 100644
--- a/cpukit/libfs/src/imfs/imfs_creat.c
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -100,6 +100,10 @@ IMFS_jnode_t *IMFS_create_node(
node->info.device.minor = info->device.minor;
break;
+ case IMFS_LINEAR_FILE:
+ node->info.linearfile.size = 0;
+ node->info.linearfile.direct = 0;
+
case IMFS_MEMORY_FILE:
node->info.file.size = 0;
node->info.file.indirect = 0;
diff --git a/cpukit/libfs/src/imfs/imfs_debug.c b/cpukit/libfs/src/imfs/imfs_debug.c
index 42d19abddf..89e1bc91ce 100644
--- a/cpukit/libfs/src/imfs/imfs_debug.c
+++ b/cpukit/libfs/src/imfs/imfs_debug.c
@@ -34,7 +34,8 @@ char *IMFS_types[ IMFS_NUMBER_OF_TYPES ] = {
"directory",
"device",
"link",
- "memory file"
+ "memory file",
+ "linear file"
};
/*
@@ -60,6 +61,13 @@ void IMFS_print_jnode(
the_jnode->info.device.major, the_jnode->info.device.minor );
break;
+ case IMFS_LINEAR_FILE:
+ printf( " (file %d %p)",
+ (int)the_jnode->info.linearfile.size,
+ the_jnode->info.linearfile.direct
+ );
+ break;
+
case IMFS_MEMORY_FILE:
printf( " (file %d %p %p %p)",
(int)the_jnode->info.file.size,
diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c
index 913fddeaa7..da2231f16a 100644
--- a/cpukit/libfs/src/imfs/imfs_eval.c
+++ b/cpukit/libfs/src/imfs/imfs_eval.c
@@ -46,6 +46,9 @@ int IMFS_Set_handlers(
case IMFS_HARD_LINK:
loc->handlers = &IMFS_link_handlers;
break;
+ case IMFS_LINEAR_FILE:
+ loc->handlers = fs_info->linearfile_handlers;
+ break;
case IMFS_MEMORY_FILE:
loc->handlers = fs_info->memfile_handlers;
break;
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
index 5133b87198..eb2ab47b39 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
@@ -19,6 +19,23 @@
* Set of operations handlers for operations on memfile entities.
*/
+rtems_filesystem_file_handlers_r IMFS_linearfile_handlers = {
+ memfile_open,
+ memfile_close,
+ linearfile_read,
+ NULL, /* write */
+ memfile_ioctl,
+ linearfile_lseek,
+ IMFS_stat,
+ NULL, /* chmod */
+ NULL, /* ftruncate */
+ NULL, /* fpathconf */
+ IMFS_fdatasync, /* fsync */
+ IMFS_fdatasync,
+ IMFS_fcntl,
+ NULL /* rmnod */
+};
+
rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
memfile_open,
memfile_close,
diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c
index 0f9342b381..46a578f586 100644
--- a/cpukit/libfs/src/imfs/imfs_init.c
+++ b/cpukit/libfs/src/imfs/imfs_init.c
@@ -59,6 +59,7 @@ int IMFS_initialize(
IMFS_initialize_support(
temp_mt_entry,
&IMFS_ops,
+ &IMFS_linearfile_handlers,
&IMFS_memfile_handlers,
&IMFS_directory_handlers
);
diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c
index 1e9bb380b1..cf1a48e480 100644
--- a/cpukit/libfs/src/imfs/imfs_initsupp.c
+++ b/cpukit/libfs/src/imfs/imfs_initsupp.c
@@ -32,6 +32,7 @@
int IMFS_initialize_support(
rtems_filesystem_mount_table_entry_t *temp_mt_entry,
rtems_filesystem_operations_table *op_table,
+ rtems_filesystem_file_handlers_r *linearfile_handlers,
rtems_filesystem_file_handlers_r *memfile_handlers,
rtems_filesystem_file_handlers_r *directory_handlers
)
@@ -69,9 +70,10 @@ int IMFS_initialize_support(
* Set st_ino for the root to 1.
*/
- fs_info->ino_count = 1;
- fs_info->memfile_handlers = memfile_handlers;
- fs_info->directory_handlers = directory_handlers;
+ fs_info->ino_count = 1;
+ fs_info->linearfile_handlers = linearfile_handlers;
+ fs_info->memfile_handlers = memfile_handlers;
+ fs_info->directory_handlers = directory_handlers;
jnode = temp_mt_entry->mt_fs_root.node_access;
jnode->st_ino = fs_info->ino_count;
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
new file mode 100644
index 0000000000..7dc7df8a61
--- /dev/null
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -0,0 +1,209 @@
+/**************************************************************************
+ * This file implements the "mount" procedure for tar-based IMFS
+ * extensions. The TAR is not actually mounted under the IMFS.
+ * Directories from the TAR file are created as usual in the IMFS.
+ * File entries are created as IMFS_LINEAR_FILE nodes with their nods
+ * pointing to addresses in the TAR image.
+ *
+ * $Id$
+ *
+ *************************************************************************/
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <string.h>
+#include <chain.h>
+#include <imfs.h>
+
+
+/**************************************************************************
+ * TAR file format:
+ *
+ * Offset Length Contents
+ * 0 100 bytes File name ('\0' terminated, 99 maxmum length)
+ * 100 8 bytes File mode (in octal ascii)
+ * 108 8 bytes User ID (in octal ascii)
+ * 116 8 bytes Group ID (in octal ascii)
+ * 124 12 bytes File size (s) (in octal ascii)
+ * 136 12 bytes Modify time (in octal ascii)
+ * 148 8 bytes Header checksum (in octal ascii)
+ * 156 1 bytes Link flag
+ * 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
+ * 257 8 bytes Magic ("ustar \0")
+ * 265 32 bytes User name ('\0' terminated, 31 maxmum length)
+ * 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
+ * 329 8 bytes Major device ID (in octal ascii)
+ * 337 8 bytes Minor device ID (in octal ascii)
+ * 345 167 bytes Padding
+ * 512 (s+p)bytes File contents (s+p) := (((s) + 511) & ~511),
+ * round up to 512 bytes
+ *
+ * Checksum:
+ * int i, sum;
+ * char* header = tar_header_pointer;
+ * sum = 0;
+ * for(i = 0; i < 512; i++)
+ * sum += 0xFF & header[i];
+ *************************************************************************/
+
+#define LF_OLDNORMAL '\0' /* Normal disk file, Unix compatible */
+#define LF_NORMAL '0' /* Normal disk file */
+#define LF_LINK '1' /* Link to previously dumped file */
+#define LF_SYMLINK '2' /* Symbolic link */
+#define LF_CHR '3' /* Character special file */
+#define LF_BLK '4' /* Block special file */
+#define LF_DIR '5' /* Directory */
+#define LF_FIFO '6' /* FIFO special file */
+#define LF_CONFIG '7' /* Contiguous file */
+
+#define MAX_NAME_FIELD_SIZE 99
+
+#define MIN(a,b) ((a)>(b)?(b):(a))
+
+
+/**************************************************************************
+ * This converts octal ASCII number representations into an
+ * unsigned long. Only support 32-bit numbers for now.
+ *************************************************************************/
+static unsigned long
+octal2ulong(char *octascii, int len)
+{
+ int i;
+ unsigned long num;
+ unsigned long mult;
+
+ num = 0;
+ mult = 1;
+ for (i=len-1; i>=0; i--)
+ {
+ if ((octascii[i] < '0') || (octascii[i] > '9'))
+ continue;
+
+ num += mult*((unsigned long)(octascii[i] - '0'));
+ mult *= 8;
+ }
+ return(num);
+}
+
+
+/************************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ************************************************************************/
+static int
+compute_tar_header_checksum(char *bufr)
+{
+ int i, sum;
+
+
+ sum = 0;
+ for (i=0; i<512; i++)
+ {
+ if ((i >= 148) && (i < 156))
+ sum += 0xff & ' ';
+ else
+ sum += 0xff & bufr[i];
+ }
+ return(sum);
+}
+
+
+/**************************************************************************
+ * rtems_tarfs_mount
+ *
+ * Here we create the mountpoint directory and mount the tarfs at
+ * that node. Once the IMFS has been mounted, we work through the
+ * tar image and perform as follows:
+ * - For directories, simply call mkdir(). The IMFS creates nodes as
+ * needed.
+ * - For files, we make our own calls to IMFS eval_for_make and
+ * create_node.
+ *************************************************************************/
+int
+rtems_tarfs_mount(char *mountpoint,
+ unsigned char *tar_image,
+ unsigned long tar_size)
+{
+ rtems_filesystem_location_info_t root_loc;
+ rtems_filesystem_location_info_t loc;
+ char *hdr_ptr;
+ char filename[100];
+ char full_filename[256];
+ int hdr_chksum;
+ unsigned char linkflag;
+ unsigned long file_size;
+ int offset;
+ unsigned long nblocks;
+ IMFS_jnode_t *node;
+ int status;
+
+
+ status = rtems_filesystem_evaluate_path(mountpoint, 0, &root_loc, 0);
+ if (status != 0)
+ return(-1);
+
+ /***********************************************************************
+ * Create an IMFS node structure pointing to tar image memory.
+ **********************************************************************/
+ offset = 0;
+ while (1)
+ {
+ if (offset + 512 > tar_size)
+ break;
+
+ /******************************************************************
+ * Read a header.
+ ******************************************************************/
+ hdr_ptr = &tar_image[offset];
+ offset += 512;
+ if (strncmp(&hdr_ptr[257], "ustar ", 7))
+ break;
+
+ strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
+ filename[MAX_NAME_FIELD_SIZE] = '\0';
+
+ linkflag = hdr_ptr[156];
+ file_size = octal2ulong(&hdr_ptr[124], 12);
+
+ hdr_chksum = (int)octal2ulong(&hdr_ptr[148], 8);
+ if (compute_tar_header_checksum(hdr_ptr) != hdr_chksum)
+ break;
+
+ /******************************************************************
+ * Generate an IMFS node depending on the file type.
+ * - For directories, just create directories as usual. IMFS
+ * will take care of the rest.
+ * - For files, create a file node with special tarfs properties.
+ *****************************************************************/
+ if (linkflag == LF_DIR)
+ {
+ strcpy(full_filename, mountpoint);
+ strcat(full_filename, "/");
+ strcat(full_filename, filename);
+ mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
+ }
+ else if (linkflag == LF_NORMAL)
+ {
+ const char *name;
+
+
+ loc = root_loc;
+ if (IMFS_evaluate_for_make(filename, &loc, &name) == 0)
+ {
+ node = IMFS_create_node(&loc,
+ IMFS_LINEAR_FILE, (char *)name,
+ (S_IRUSR | S_IRGRP | S_IROTH) | S_IFREG,
+ NULL);
+ node->info.linearfile.size = file_size;
+ node->info.linearfile.direct = &tar_image[offset];
+ }
+
+ nblocks = (((file_size) + 511) & ~511) / 512;
+ offset += 512 * nblocks;
+ }
+ }
+
+ return(status);
+}
+
diff --git a/cpukit/libfs/src/imfs/imfs_stat.c b/cpukit/libfs/src/imfs/imfs_stat.c
index e01f33794b..ee4971df4e 100644
--- a/cpukit/libfs/src/imfs/imfs_stat.c
+++ b/cpukit/libfs/src/imfs/imfs_stat.c
@@ -35,6 +35,7 @@ int IMFS_stat(
buf->st_dev = rtems_filesystem_make_dev_t( io->major, io->minor );
break;
+ case IMFS_LINEAR_FILE:
case IMFS_MEMORY_FILE:
buf->st_size = the_jnode->info.file.size;
break;
diff --git a/cpukit/libfs/src/imfs/linearfile.c b/cpukit/libfs/src/imfs/linearfile.c
new file mode 100644
index 0000000000..e8d28fe31d
--- /dev/null
+++ b/cpukit/libfs/src/imfs/linearfile.c
@@ -0,0 +1,110 @@
+/*
+ * IMFS Linear File Handlers
+ *
+ * This file contains the set of handlers used to process operations on
+ * IMFS linear memory file nodes. Linear memory files are contiguous
+ * blocks of memory created from a TAR or other filesystem image.
+ * The blocks are nonwriteable and nonresizeable.
+ *
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include "imfs.h"
+#include <rtems/libio_.h>
+
+/*
+ * linearfile_read
+ *
+ * This routine processes the read() system call.
+ */
+
+int linearfile_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ unsigned32 count
+)
+{
+ IMFS_jnode_t *the_jnode;
+ unsigned char *dest;
+ unsigned char *file_ptr;
+ int file_offset;
+
+
+ the_jnode = iop->file_info;
+
+ /*
+ * Perform internal consistency checks
+ */
+
+ assert( the_jnode );
+ if ( !the_jnode )
+ set_errno_and_return_minus_one( EIO );
+
+ assert( the_jnode->type == IMFS_LINEAR_FILE );
+ if ( the_jnode->type != IMFS_LINEAR_FILE )
+ set_errno_and_return_minus_one( EIO );
+
+ /*
+ * Error checks on arguments
+ */
+
+ dest = (unsigned char *)buffer;
+ assert( dest );
+ if ( !dest )
+ set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * Perform a simple memory copy.
+ */
+
+ if (count == 0)
+ return(0);
+
+ the_jnode = iop->file_info;
+ file_ptr = (unsigned char *)the_jnode->info.linearfile.direct;
+ file_offset = (unsigned long)iop->offset;
+
+ if (count > (the_jnode->info.linearfile.size - file_offset))
+ count = the_jnode->info.linearfile.size - file_offset;
+
+ memcpy(dest, &file_ptr[file_offset], count);
+
+ return(count);
+}
+
+
+/*
+ * linearfile_lseek
+ *
+ * This routine processes the lseek() system call.
+ */
+
+int linearfile_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+)
+{
+ IMFS_jnode_t *the_jnode;
+
+ the_jnode = iop->file_info;
+
+ if (iop->offset > the_jnode->info.linearfile.size)
+ iop->offset = the_jnode->info.linearfile.size;
+
+ return iop->offset;
+}
+
diff --git a/cpukit/libfs/src/imfs/miniimfs_init.c b/cpukit/libfs/src/imfs/miniimfs_init.c
index f752fc1f87..138cab8b27 100644
--- a/cpukit/libfs/src/imfs/miniimfs_init.c
+++ b/cpukit/libfs/src/imfs/miniimfs_init.c
@@ -59,6 +59,7 @@ int miniIMFS_initialize(
IMFS_initialize_support(
temp_mt_entry,
&miniIMFS_ops,
+ &rtems_filesystem_null_handlers, /* for linearfiles */
&rtems_filesystem_null_handlers, /* for memfiles */
&rtems_filesystem_null_handlers /* for directories */
);