summaryrefslogtreecommitdiffstats
path: root/c/src
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2001-09-19 17:29:42 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2001-09-19 17:29:42 +0000
commitd34d2e695714fcaf3827ac0132d19f5781b986d0 (patch)
tree801edfaeeb00baf764e51a2c48b85e7dcbc7b4c3 /c/src
parent5dfa8c1e4450e09b3d2d1f0fc7ea3a8f32e09a4e (diff)
downloadrtems-d34d2e695714fcaf3827ac0132d19f5781b986d0.tar.bz2
2001-09-19 Chris Johns <ccj@acm.org>
* Added support for populating the initial "root" filesystem with information obtained via the DHCP response. * rootfs: New directory. * rootfs/.cvsignore, rootfs/Makefile.am, rootfs/mkrootfs.c, rootfs/mkrootfs.h: New files. * configure.in, Makefile.am: Modified to reflect addition.
Diffstat (limited to 'c/src')
-rw-r--r--c/src/exec/libnetworking/rtems/mkrootfs.c348
-rw-r--r--c/src/exec/libnetworking/rtems/mkrootfs.h67
-rw-r--r--c/src/libmisc/ChangeLog9
-rw-r--r--c/src/libmisc/Makefile.am2
-rw-r--r--c/src/libmisc/configure.in1
-rw-r--r--c/src/libmisc/rootfs/.cvsignore2
-rw-r--r--c/src/libmisc/rootfs/Makefile.am41
-rw-r--r--c/src/libmisc/rootfs/mkrootfs.c348
-rw-r--r--c/src/libmisc/rootfs/mkrootfs.h67
-rw-r--r--c/src/libnetworking/rtems/mkrootfs.c348
-rw-r--r--c/src/libnetworking/rtems/mkrootfs.h67
11 files changed, 1299 insertions, 1 deletions
diff --git a/c/src/exec/libnetworking/rtems/mkrootfs.c b/c/src/exec/libnetworking/rtems/mkrootfs.c
new file mode 100644
index 0000000000..d8c6301b6a
--- /dev/null
+++ b/c/src/exec/libnetworking/rtems/mkrootfs.c
@@ -0,0 +1,348 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ Set of helpers when creating a root file system. The root filesystem
+ in RTEMS is the In Memory Filesystem (IMFS). We could copy an exiting
+ filesystem to here, how-ever a number of files can have target
+ specific initialisation info which we need to write.
+
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rtems/mkrootfs.h>
+
+/*
+ * A table a list of names and their modes.
+ */
+
+typedef struct rtems_rootfs_dir_table
+{
+ const char *name;
+ int mode;
+} rtems_rootfs_dir_table;
+
+/*
+ * Table of directorys to make.
+ */
+
+static const rtems_rootfs_dir_table default_directories[] =
+{
+ { "/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/etc", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/dev", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/usr/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH }
+};
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+#define MKDIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+/*
+ * Build a path. Taken from the BSD `mkdir' command.
+ */
+
+int
+rtems_rootfs_mkdir (const char *path_orig, mode_t omode)
+{
+ struct stat sb;
+ mode_t numask, oumask;
+ int first, last, retval;
+ char path[128];
+ char *p = path;
+
+ if (strlen (path_orig) >= sizeof path)
+ {
+ printf ("root fs: mkdir path too long `%s'\n", path);
+ return -1;
+ }
+
+ strcpy (path, path_orig);
+ oumask = 0;
+ retval = 0;
+ if (p[0] == '/') /* Skip leading '/'. */
+ ++p;
+ for (first = 1, last = 0; !last ; ++p)
+ {
+ if (p[0] == '\0')
+ last = 1;
+ else if (p[0] != '/')
+ continue;
+ *p = '\0';
+ if (p[1] == '\0')
+ last = 1;
+ if (first)
+ {
+ /*
+ * POSIX 1003.2:
+ * For each dir operand that does not name an existing
+ * directory, effects equivalent to those cased by the
+ * following command shall occcur:
+ *
+ * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
+ * mkdir [-m mode] dir
+ *
+ * We change the user's umask and then restore it,
+ * instead of doing chmod's.
+ */
+ oumask = umask(0);
+ numask = oumask & ~(S_IWUSR | S_IXUSR);
+ umask(numask);
+ first = 0;
+ }
+ if (last)
+ umask(oumask);
+ if (stat(path, &sb))
+ {
+ if (errno != ENOENT)
+ {
+ printf ("root fs: error stat'ing path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+ {
+ printf ("root fs: error building path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ }
+ else if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ {
+ if (last)
+ errno = EEXIST;
+ else
+ errno = ENOTDIR;
+ printf ("root fs: path `%s' contains a file, %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (!last)
+ *p = '/';
+ }
+ if (!first && !last)
+ umask(oumask);
+ return retval;
+}
+
+/*
+ * Create enough files to support the networking stack.
+ * Points to a table of strings.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines)
+{
+ struct stat sb;
+ int fd;
+ int i;
+
+ /*
+ * See is a file exists. If it does not, create the
+ * file and the path to the file.
+ */
+
+ fd = -1;
+
+ if (stat(file, &sb))
+ {
+ if (errno == ENOENT)
+ {
+ /*
+ * Get the path to the file if one exists and create the
+ * path. If it exists nothing happens.
+ */
+
+ int i = strlen (file);
+
+ while (i)
+ {
+ if (file[i] == '/')
+ {
+ char path[128];
+
+ if (i >= sizeof path)
+ {
+ printf ("root fs, path too long `%s'\n", file);
+ return -1;
+ }
+
+ strncpy (path, file, i);
+ path[i] = '\0';
+
+ if (rtems_rootfs_mkdir (path, MKDIR_MODE))
+ return -1;
+ break;
+ }
+ i--;
+ }
+
+ if ((fd = open (file, O_CREAT | O_APPEND | O_WRONLY, omode)) < 0)
+ {
+ printf ("root fs, cannot create file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ if (fd < 0)
+ {
+ if ((fd = open (file, O_APPEND | O_WRONLY)) < 0)
+ {
+ printf ("root fs, cannot open file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+
+ for (i = 0; i < line_cnt; i++)
+ {
+ int len = strlen (lines[i]);
+
+ if (len)
+ {
+ if (write (fd, lines[i], strlen (lines[i])) < 0)
+ {
+ close (fd);
+ printf ("root fs, cannot write to `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ return close (fd);
+}
+
+/*
+ * Write hosts record.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname)
+{
+ char buf[128];
+ char *bufp = buf;
+ const char *bufl[1];
+ struct in_addr ip;
+
+ ip.s_addr = cip;
+
+ if (cname && strlen (cname))
+ {
+ snprintf (bufp, sizeof (buf), "%s\t\t%s", inet_ntoa (ip), cname);
+ bufp += strlen (buf);
+
+ if (dname && strlen (dname))
+ {
+ snprintf (bufp, sizeof (buf), "\t\t%s.%s", cname, dname);
+ bufp += strlen (buf);
+ }
+
+ strcat (buf, "\n");
+
+ bufl[0] = buf;
+
+ if (rtems_rootfs_file_append ("/etc/hosts", MKFILE_MODE, 1, bufl) < 0)
+ return -1;
+ }
+ else
+ {
+ printf ("rootfs hosts rec append, no cname supplied\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a root file system.
+ */
+
+int
+rtems_create_root_fs ()
+{
+ const char *lines[1];
+ int i;
+
+ /*
+ * Create the directories.
+ */
+
+ for (i = 0;
+ i < (sizeof (default_directories) / sizeof (rtems_rootfs_dir_table));
+ i++)
+ if (rtems_rootfs_mkdir (default_directories[i].name,
+ default_directories[i].mode))
+ return -1;
+
+ /*
+ * /etc/passwd, /etc/group
+ * Maybe needed by some tools.
+ */
+
+ lines[0] = "root::0:0:root:/root:/bin/sh\n";
+
+ if (rtems_rootfs_file_append ("/etc/passwd", MKFILE_MODE, 1, lines))
+ return -1;
+
+ lines[0] = "root::0:root\n";
+
+ if (rtems_rootfs_file_append ("/etc/group", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * The TCP/IP stack likes this one. If DNS does not work
+ * use the host file.
+ */
+
+ lines[0] = "hosts,bind\n";
+
+ if (rtems_rootfs_file_append ("/etc/host.conf", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * Create a `/etc/hosts' file.
+ */
+
+ if (rtems_rootfs_append_host_rec (0x7f000001, "localhost", "localdomain"))
+ return -1;
+
+ return 0;
+}
+
diff --git a/c/src/exec/libnetworking/rtems/mkrootfs.h b/c/src/exec/libnetworking/rtems/mkrootfs.h
new file mode 100644
index 0000000000..ac9d697da4
--- /dev/null
+++ b/c/src/exec/libnetworking/rtems/mkrootfs.h
@@ -0,0 +1,67 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Root FS creatation support.
+
+*/
+
+#ifndef __RTEMS_MKROOTFS_h
+#define __RTEMS_MKROOTFS_h
+
+#include <rtems.h>
+
+/*
+ * Builds the complete path, like "mkdir -p".
+ */
+
+int
+rtems_rootfs_mkdir (const char *path, mode_t omode);
+
+/*
+ * Appends the lines to the a file. Create the file
+ * and builds the path if it does not exist.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines);
+
+/*
+ * Helper for bulding an /etc/hosts file.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname);
+
+/*
+ * Create a few common directories, plus a :
+ * /etc/passwd, /etc/group, /etc/host.conf, and
+ * /etc/hosts file.
+ */
+
+int
+rtems_create_root_fs ();
+
+#endif
diff --git a/c/src/libmisc/ChangeLog b/c/src/libmisc/ChangeLog
index 94f7565ae2..ff0043e6b0 100644
--- a/c/src/libmisc/ChangeLog
+++ b/c/src/libmisc/ChangeLog
@@ -1,3 +1,12 @@
+2001-09-19 Chris Johns <ccj@acm.org>
+
+ * Added support for populating the initial "root" filesystem
+ with information obtained via the DHCP response.
+ * rootfs: New directory.
+ * rootfs/.cvsignore, rootfs/Makefile.am, rootfs/mkrootfs.c,
+ rootfs/mkrootfs.h: New files.
+ * configure.in, Makefile.am: Modified to reflect addition.
+
2001-09-14 Fernando Ruiz <fernando.ruiz@ctv.es>
* shell/shell.c: Don't close file it wasn't open.
diff --git a/c/src/libmisc/Makefile.am b/c/src/libmisc/Makefile.am
index 39f14528ea..f3d19e1625 100644
--- a/c/src/libmisc/Makefile.am
+++ b/c/src/libmisc/Makefile.am
@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I ../../../aclocal
-SUBDIRS = devnull dummy dumpbuf stackchk monitor cpuuse shell rtmonuse untar \
+SUBDIRS = devnull dummy dumpbuf stackchk monitor cpuuse shell rtmonuse rootfs untar \
mw-fb wrapup
EXTRA_DIST = README
diff --git a/c/src/libmisc/configure.in b/c/src/libmisc/configure.in
index 664485b1d4..0ddca985dd 100644
--- a/c/src/libmisc/configure.in
+++ b/c/src/libmisc/configure.in
@@ -39,6 +39,7 @@ dummy/Makefile
dumpbuf/Makefile
monitor/Makefile
rtmonuse/Makefile
+rootfs/Makefile
stackchk/Makefile
untar/Makefile
mw-fb/Makefile
diff --git a/c/src/libmisc/rootfs/.cvsignore b/c/src/libmisc/rootfs/.cvsignore
new file mode 100644
index 0000000000..282522db03
--- /dev/null
+++ b/c/src/libmisc/rootfs/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/c/src/libmisc/rootfs/Makefile.am b/c/src/libmisc/rootfs/Makefile.am
new file mode 100644
index 0000000000..891cbd88e1
--- /dev/null
+++ b/c/src/libmisc/rootfs/Makefile.am
@@ -0,0 +1,41 @@
+##
+## $Id$
+##
+
+AUTOMAKE_OPTIONS = foreign 1.4
+
+LIBNAME = librootfs-tmp
+LIB = $(ARCH)/$(LIBNAME).a
+
+C_FILES = mkrootfs.c
+C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+
+H_FILES = mkrootfs.h
+
+OBJS = $(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../../../automake/lib.am
+
+$(PROJECT_INCLUDE)/rtems:
+ @$(mkinstalldirs) $@
+$(PROJECT_INCLUDE)/rtems/%.h: %.h
+ $(INSTALL_DATA) $< $@
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+$(LIB): $(OBJS)
+ $(make-library)
+
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems \
+ $(H_FILES:%=$(PROJECT_INCLUDE)/rtems/%)
+
+all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
+
+.PRECIOUS: $(LIB)
+
+EXTRA_DIST = README mkrootfs.c mkrootfs.h
+
+include $(top_srcdir)/../../../automake/local.am
diff --git a/c/src/libmisc/rootfs/mkrootfs.c b/c/src/libmisc/rootfs/mkrootfs.c
new file mode 100644
index 0000000000..d8c6301b6a
--- /dev/null
+++ b/c/src/libmisc/rootfs/mkrootfs.c
@@ -0,0 +1,348 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ Set of helpers when creating a root file system. The root filesystem
+ in RTEMS is the In Memory Filesystem (IMFS). We could copy an exiting
+ filesystem to here, how-ever a number of files can have target
+ specific initialisation info which we need to write.
+
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rtems/mkrootfs.h>
+
+/*
+ * A table a list of names and their modes.
+ */
+
+typedef struct rtems_rootfs_dir_table
+{
+ const char *name;
+ int mode;
+} rtems_rootfs_dir_table;
+
+/*
+ * Table of directorys to make.
+ */
+
+static const rtems_rootfs_dir_table default_directories[] =
+{
+ { "/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/etc", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/dev", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/usr/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH }
+};
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+#define MKDIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+/*
+ * Build a path. Taken from the BSD `mkdir' command.
+ */
+
+int
+rtems_rootfs_mkdir (const char *path_orig, mode_t omode)
+{
+ struct stat sb;
+ mode_t numask, oumask;
+ int first, last, retval;
+ char path[128];
+ char *p = path;
+
+ if (strlen (path_orig) >= sizeof path)
+ {
+ printf ("root fs: mkdir path too long `%s'\n", path);
+ return -1;
+ }
+
+ strcpy (path, path_orig);
+ oumask = 0;
+ retval = 0;
+ if (p[0] == '/') /* Skip leading '/'. */
+ ++p;
+ for (first = 1, last = 0; !last ; ++p)
+ {
+ if (p[0] == '\0')
+ last = 1;
+ else if (p[0] != '/')
+ continue;
+ *p = '\0';
+ if (p[1] == '\0')
+ last = 1;
+ if (first)
+ {
+ /*
+ * POSIX 1003.2:
+ * For each dir operand that does not name an existing
+ * directory, effects equivalent to those cased by the
+ * following command shall occcur:
+ *
+ * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
+ * mkdir [-m mode] dir
+ *
+ * We change the user's umask and then restore it,
+ * instead of doing chmod's.
+ */
+ oumask = umask(0);
+ numask = oumask & ~(S_IWUSR | S_IXUSR);
+ umask(numask);
+ first = 0;
+ }
+ if (last)
+ umask(oumask);
+ if (stat(path, &sb))
+ {
+ if (errno != ENOENT)
+ {
+ printf ("root fs: error stat'ing path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+ {
+ printf ("root fs: error building path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ }
+ else if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ {
+ if (last)
+ errno = EEXIST;
+ else
+ errno = ENOTDIR;
+ printf ("root fs: path `%s' contains a file, %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (!last)
+ *p = '/';
+ }
+ if (!first && !last)
+ umask(oumask);
+ return retval;
+}
+
+/*
+ * Create enough files to support the networking stack.
+ * Points to a table of strings.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines)
+{
+ struct stat sb;
+ int fd;
+ int i;
+
+ /*
+ * See is a file exists. If it does not, create the
+ * file and the path to the file.
+ */
+
+ fd = -1;
+
+ if (stat(file, &sb))
+ {
+ if (errno == ENOENT)
+ {
+ /*
+ * Get the path to the file if one exists and create the
+ * path. If it exists nothing happens.
+ */
+
+ int i = strlen (file);
+
+ while (i)
+ {
+ if (file[i] == '/')
+ {
+ char path[128];
+
+ if (i >= sizeof path)
+ {
+ printf ("root fs, path too long `%s'\n", file);
+ return -1;
+ }
+
+ strncpy (path, file, i);
+ path[i] = '\0';
+
+ if (rtems_rootfs_mkdir (path, MKDIR_MODE))
+ return -1;
+ break;
+ }
+ i--;
+ }
+
+ if ((fd = open (file, O_CREAT | O_APPEND | O_WRONLY, omode)) < 0)
+ {
+ printf ("root fs, cannot create file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ if (fd < 0)
+ {
+ if ((fd = open (file, O_APPEND | O_WRONLY)) < 0)
+ {
+ printf ("root fs, cannot open file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+
+ for (i = 0; i < line_cnt; i++)
+ {
+ int len = strlen (lines[i]);
+
+ if (len)
+ {
+ if (write (fd, lines[i], strlen (lines[i])) < 0)
+ {
+ close (fd);
+ printf ("root fs, cannot write to `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ return close (fd);
+}
+
+/*
+ * Write hosts record.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname)
+{
+ char buf[128];
+ char *bufp = buf;
+ const char *bufl[1];
+ struct in_addr ip;
+
+ ip.s_addr = cip;
+
+ if (cname && strlen (cname))
+ {
+ snprintf (bufp, sizeof (buf), "%s\t\t%s", inet_ntoa (ip), cname);
+ bufp += strlen (buf);
+
+ if (dname && strlen (dname))
+ {
+ snprintf (bufp, sizeof (buf), "\t\t%s.%s", cname, dname);
+ bufp += strlen (buf);
+ }
+
+ strcat (buf, "\n");
+
+ bufl[0] = buf;
+
+ if (rtems_rootfs_file_append ("/etc/hosts", MKFILE_MODE, 1, bufl) < 0)
+ return -1;
+ }
+ else
+ {
+ printf ("rootfs hosts rec append, no cname supplied\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a root file system.
+ */
+
+int
+rtems_create_root_fs ()
+{
+ const char *lines[1];
+ int i;
+
+ /*
+ * Create the directories.
+ */
+
+ for (i = 0;
+ i < (sizeof (default_directories) / sizeof (rtems_rootfs_dir_table));
+ i++)
+ if (rtems_rootfs_mkdir (default_directories[i].name,
+ default_directories[i].mode))
+ return -1;
+
+ /*
+ * /etc/passwd, /etc/group
+ * Maybe needed by some tools.
+ */
+
+ lines[0] = "root::0:0:root:/root:/bin/sh\n";
+
+ if (rtems_rootfs_file_append ("/etc/passwd", MKFILE_MODE, 1, lines))
+ return -1;
+
+ lines[0] = "root::0:root\n";
+
+ if (rtems_rootfs_file_append ("/etc/group", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * The TCP/IP stack likes this one. If DNS does not work
+ * use the host file.
+ */
+
+ lines[0] = "hosts,bind\n";
+
+ if (rtems_rootfs_file_append ("/etc/host.conf", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * Create a `/etc/hosts' file.
+ */
+
+ if (rtems_rootfs_append_host_rec (0x7f000001, "localhost", "localdomain"))
+ return -1;
+
+ return 0;
+}
+
diff --git a/c/src/libmisc/rootfs/mkrootfs.h b/c/src/libmisc/rootfs/mkrootfs.h
new file mode 100644
index 0000000000..ac9d697da4
--- /dev/null
+++ b/c/src/libmisc/rootfs/mkrootfs.h
@@ -0,0 +1,67 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Root FS creatation support.
+
+*/
+
+#ifndef __RTEMS_MKROOTFS_h
+#define __RTEMS_MKROOTFS_h
+
+#include <rtems.h>
+
+/*
+ * Builds the complete path, like "mkdir -p".
+ */
+
+int
+rtems_rootfs_mkdir (const char *path, mode_t omode);
+
+/*
+ * Appends the lines to the a file. Create the file
+ * and builds the path if it does not exist.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines);
+
+/*
+ * Helper for bulding an /etc/hosts file.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname);
+
+/*
+ * Create a few common directories, plus a :
+ * /etc/passwd, /etc/group, /etc/host.conf, and
+ * /etc/hosts file.
+ */
+
+int
+rtems_create_root_fs ();
+
+#endif
diff --git a/c/src/libnetworking/rtems/mkrootfs.c b/c/src/libnetworking/rtems/mkrootfs.c
new file mode 100644
index 0000000000..d8c6301b6a
--- /dev/null
+++ b/c/src/libnetworking/rtems/mkrootfs.c
@@ -0,0 +1,348 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ Set of helpers when creating a root file system. The root filesystem
+ in RTEMS is the In Memory Filesystem (IMFS). We could copy an exiting
+ filesystem to here, how-ever a number of files can have target
+ specific initialisation info which we need to write.
+
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <rtems/mkrootfs.h>
+
+/*
+ * A table a list of names and their modes.
+ */
+
+typedef struct rtems_rootfs_dir_table
+{
+ const char *name;
+ int mode;
+} rtems_rootfs_dir_table;
+
+/*
+ * Table of directorys to make.
+ */
+
+static const rtems_rootfs_dir_table default_directories[] =
+{
+ { "/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/etc", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/dev", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
+ { "/usr/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH }
+};
+
+#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
+#define MKDIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+/*
+ * Build a path. Taken from the BSD `mkdir' command.
+ */
+
+int
+rtems_rootfs_mkdir (const char *path_orig, mode_t omode)
+{
+ struct stat sb;
+ mode_t numask, oumask;
+ int first, last, retval;
+ char path[128];
+ char *p = path;
+
+ if (strlen (path_orig) >= sizeof path)
+ {
+ printf ("root fs: mkdir path too long `%s'\n", path);
+ return -1;
+ }
+
+ strcpy (path, path_orig);
+ oumask = 0;
+ retval = 0;
+ if (p[0] == '/') /* Skip leading '/'. */
+ ++p;
+ for (first = 1, last = 0; !last ; ++p)
+ {
+ if (p[0] == '\0')
+ last = 1;
+ else if (p[0] != '/')
+ continue;
+ *p = '\0';
+ if (p[1] == '\0')
+ last = 1;
+ if (first)
+ {
+ /*
+ * POSIX 1003.2:
+ * For each dir operand that does not name an existing
+ * directory, effects equivalent to those cased by the
+ * following command shall occcur:
+ *
+ * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
+ * mkdir [-m mode] dir
+ *
+ * We change the user's umask and then restore it,
+ * instead of doing chmod's.
+ */
+ oumask = umask(0);
+ numask = oumask & ~(S_IWUSR | S_IXUSR);
+ umask(numask);
+ first = 0;
+ }
+ if (last)
+ umask(oumask);
+ if (stat(path, &sb))
+ {
+ if (errno != ENOENT)
+ {
+ printf ("root fs: error stat'ing path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
+ {
+ printf ("root fs: error building path `%s', %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ }
+ else if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ {
+ if (last)
+ errno = EEXIST;
+ else
+ errno = ENOTDIR;
+ printf ("root fs: path `%s' contains a file, %s\n",
+ path, strerror (errno));
+ retval = 1;
+ break;
+ }
+ if (!last)
+ *p = '/';
+ }
+ if (!first && !last)
+ umask(oumask);
+ return retval;
+}
+
+/*
+ * Create enough files to support the networking stack.
+ * Points to a table of strings.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines)
+{
+ struct stat sb;
+ int fd;
+ int i;
+
+ /*
+ * See is a file exists. If it does not, create the
+ * file and the path to the file.
+ */
+
+ fd = -1;
+
+ if (stat(file, &sb))
+ {
+ if (errno == ENOENT)
+ {
+ /*
+ * Get the path to the file if one exists and create the
+ * path. If it exists nothing happens.
+ */
+
+ int i = strlen (file);
+
+ while (i)
+ {
+ if (file[i] == '/')
+ {
+ char path[128];
+
+ if (i >= sizeof path)
+ {
+ printf ("root fs, path too long `%s'\n", file);
+ return -1;
+ }
+
+ strncpy (path, file, i);
+ path[i] = '\0';
+
+ if (rtems_rootfs_mkdir (path, MKDIR_MODE))
+ return -1;
+ break;
+ }
+ i--;
+ }
+
+ if ((fd = open (file, O_CREAT | O_APPEND | O_WRONLY, omode)) < 0)
+ {
+ printf ("root fs, cannot create file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ if (fd < 0)
+ {
+ if ((fd = open (file, O_APPEND | O_WRONLY)) < 0)
+ {
+ printf ("root fs, cannot open file `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+
+ for (i = 0; i < line_cnt; i++)
+ {
+ int len = strlen (lines[i]);
+
+ if (len)
+ {
+ if (write (fd, lines[i], strlen (lines[i])) < 0)
+ {
+ close (fd);
+ printf ("root fs, cannot write to `%s' : %s\n",
+ file, strerror (errno));
+ return -1;
+ }
+ }
+ }
+
+ return close (fd);
+}
+
+/*
+ * Write hosts record.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname)
+{
+ char buf[128];
+ char *bufp = buf;
+ const char *bufl[1];
+ struct in_addr ip;
+
+ ip.s_addr = cip;
+
+ if (cname && strlen (cname))
+ {
+ snprintf (bufp, sizeof (buf), "%s\t\t%s", inet_ntoa (ip), cname);
+ bufp += strlen (buf);
+
+ if (dname && strlen (dname))
+ {
+ snprintf (bufp, sizeof (buf), "\t\t%s.%s", cname, dname);
+ bufp += strlen (buf);
+ }
+
+ strcat (buf, "\n");
+
+ bufl[0] = buf;
+
+ if (rtems_rootfs_file_append ("/etc/hosts", MKFILE_MODE, 1, bufl) < 0)
+ return -1;
+ }
+ else
+ {
+ printf ("rootfs hosts rec append, no cname supplied\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a root file system.
+ */
+
+int
+rtems_create_root_fs ()
+{
+ const char *lines[1];
+ int i;
+
+ /*
+ * Create the directories.
+ */
+
+ for (i = 0;
+ i < (sizeof (default_directories) / sizeof (rtems_rootfs_dir_table));
+ i++)
+ if (rtems_rootfs_mkdir (default_directories[i].name,
+ default_directories[i].mode))
+ return -1;
+
+ /*
+ * /etc/passwd, /etc/group
+ * Maybe needed by some tools.
+ */
+
+ lines[0] = "root::0:0:root:/root:/bin/sh\n";
+
+ if (rtems_rootfs_file_append ("/etc/passwd", MKFILE_MODE, 1, lines))
+ return -1;
+
+ lines[0] = "root::0:root\n";
+
+ if (rtems_rootfs_file_append ("/etc/group", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * The TCP/IP stack likes this one. If DNS does not work
+ * use the host file.
+ */
+
+ lines[0] = "hosts,bind\n";
+
+ if (rtems_rootfs_file_append ("/etc/host.conf", MKFILE_MODE, 1, lines))
+ return -1;
+
+ /*
+ * Create a `/etc/hosts' file.
+ */
+
+ if (rtems_rootfs_append_host_rec (0x7f000001, "localhost", "localdomain"))
+ return -1;
+
+ return 0;
+}
+
diff --git a/c/src/libnetworking/rtems/mkrootfs.h b/c/src/libnetworking/rtems/mkrootfs.h
new file mode 100644
index 0000000000..ac9d697da4
--- /dev/null
+++ b/c/src/libnetworking/rtems/mkrootfs.h
@@ -0,0 +1,67 @@
+/*
+ ------------------------------------------------------------------------
+ $Id$
+ ------------------------------------------------------------------------
+
+ Copyright Cybertec Pty Ltd, 2000
+ All rights reserved Cybertec Pty Ltd, 2000
+
+ COPYRIGHT (c) 1989-1998.
+ On-Line Applications Research Corporation (OAR).
+ Copyright assigned to U.S. Government, 1994.
+
+ 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.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Root FS creatation support.
+
+*/
+
+#ifndef __RTEMS_MKROOTFS_h
+#define __RTEMS_MKROOTFS_h
+
+#include <rtems.h>
+
+/*
+ * Builds the complete path, like "mkdir -p".
+ */
+
+int
+rtems_rootfs_mkdir (const char *path, mode_t omode);
+
+/*
+ * Appends the lines to the a file. Create the file
+ * and builds the path if it does not exist.
+ */
+
+int
+rtems_rootfs_file_append (const char *file,
+ mode_t omode,
+ const int line_cnt,
+ const char **lines);
+
+/*
+ * Helper for bulding an /etc/hosts file.
+ */
+
+int
+rtems_rootfs_append_host_rec (unsigned long cip,
+ const char *cname,
+ const char *dname);
+
+/*
+ * Create a few common directories, plus a :
+ * /etc/passwd, /etc/group, /etc/host.conf, and
+ * /etc/hosts file.
+ */
+
+int
+rtems_create_root_fs ();
+
+#endif