OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libnetworking/] [rtems/] [mkrootfs.c] - Rev 1765

Compare with Previous | Blame | View Log

/*
  ------------------------------------------------------------------------
  mkrootfs.c,v 1.2 2001/10/12 21:03:15 joel Exp
  ------------------------------------------------------------------------
 
  Copyright Cybertec Pty Ltd, 2000
  All rights reserved Cybertec Pty Ltd, 2000
 
  COPYRIGHT (c) 1989-1998.
  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.
 
  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;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.