source: rtems/cpukit/libnetworking/rtems/mkrootfs.c @ 4aa8a23

4.104.114.84.95
Last change on this file since 4aa8a23 was 4aa8a23, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/02/05 at 03:06:41

Include config.h.

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2  ------------------------------------------------------------------------
3  $Id$
4  ------------------------------------------------------------------------
5
6  Copyright Cybertec Pty Ltd, 2000
7  All rights reserved Cybertec Pty Ltd, 2000
8
9  COPYRIGHT (c) 1989-1998.
10  On-Line Applications Research Corporation (OAR).
11
12  The license and distribution terms for this file may be
13  found in the file LICENSE in this distribution or at
14
15  http://www.rtems.com/license/LICENSE.
16
17  This software with is provided ``as is'' and with NO WARRANTY.
18
19  ------------------------------------------------------------------------
20
21  Set of helpers when creating a root file system. The root filesystem
22  in RTEMS is the In Memory Filesystem (IMFS). We could copy an exiting
23  filesystem to here, how-ever a number of files can have target
24  specific initialisation info which we need to write.
25
26 */
27
28#if HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <errno.h>
33#include <stdio.h>
34#include <string.h>
35#include <sys/stat.h>
36#include <sys/types.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <arpa/inet.h>
42
43#include <rtems/mkrootfs.h>
44
45/*
46 * A table a list of names and their modes.
47 */
48
49typedef struct rtems_rootfs_dir_table
50{
51  const char *name;
52  int        mode;
53} rtems_rootfs_dir_table;
54
55/*
56 * Table of directorys to make.
57 */
58
59static const rtems_rootfs_dir_table default_directories[] =
60{
61  { "/bin",     S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
62  { "/etc",     S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
63  { "/dev",     S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH },
64  { "/usr/bin", S_IFDIR | S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH }
65};
66
67#define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)
68#define MKDIR_MODE  (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
69
70/*
71 * Build a path. Taken from the BSD `mkdir' command.
72 */
73
74int
75rtems_rootfs_mkdir (const char *path_orig, mode_t omode)
76{
77  struct stat sb;
78  mode_t      numask, oumask;
79  int         first, last, retval;
80  char        path[128];
81  char        *p = path;
82
83  if (strlen (path_orig) >= sizeof path)
84  {
85    printf ("root fs: mkdir path too long `%s'\n", path);
86    return -1;
87  }
88
89  strcpy (path, path_orig);
90  oumask = 0;
91  retval = 0;
92  if (p[0] == '/')    /* Skip leading '/'. */
93    ++p;
94  for (first = 1, last = 0; !last ; ++p)
95  {
96    if (p[0] == '\0')
97      last = 1;
98    else if (p[0] != '/')
99      continue;
100    *p = '\0';
101    if (p[1] == '\0')
102      last = 1;
103    if (first)
104    {
105      /*
106       * POSIX 1003.2:
107       * For each dir operand that does not name an existing
108       * directory, effects equivalent to those cased by the
109       * following command shall occcur:
110       *
111       * mkdir -p -m $(umask -S),u+wx $(dirname dir) &&
112       *    mkdir [-m mode] dir
113       *
114       * We change the user's umask and then restore it,
115       * instead of doing chmod's.
116       */
117      oumask = umask(0);
118      numask = oumask & ~(S_IWUSR | S_IXUSR);
119      umask(numask);
120      first = 0;
121    }
122    if (last)
123      umask(oumask);
124    if (stat(path, &sb))
125    {
126      if (errno != ENOENT)
127      {
128        printf ("root fs: error stat'ing path `%s', %s\n",
129                path, strerror (errno));
130        retval = 1;
131        break;
132      }
133      if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
134      {
135        printf ("root fs: error building path `%s', %s\n",
136                path, strerror (errno));
137        retval = 1;
138        break;
139      }
140    }
141    else if ((sb.st_mode & S_IFMT) != S_IFDIR)
142    {
143      if (last)
144        errno = EEXIST;
145      else
146        errno = ENOTDIR;
147      printf ("root fs: path `%s' contains a file, %s\n",
148              path, strerror (errno));
149      retval = 1;
150      break;
151    }
152    if (!last)
153      *p = '/';
154  }
155  if (!first && !last)
156    umask(oumask);
157  return retval;
158}
159
160/*
161 * Create enough files to support the networking stack.
162 * Points to a table of strings.
163 */
164
165int
166rtems_rootfs_file_append (const char *file,
167                          mode_t     omode,
168                          const int  line_cnt,
169                          const char **lines)
170{
171  struct stat sb;
172  int         fd;
173  int         i;
174
175  /*
176   * See is a file exists. If it does not, create the
177   * file and the path to the file.
178   */
179
180  fd = -1;
181
182  if (stat(file, &sb))
183  {
184    if (errno == ENOENT)
185    {
186      /*
187       * Get the path to the file if one exists and create the
188       * path. If it exists nothing happens.
189       */
190
191      int i = strlen (file);
192
193      while (i)
194      {
195        if (file[i] == '/')
196        {
197          char path[128];
198
199          if (i >= sizeof path)
200          {
201            printf ("root fs, path too long `%s'\n", file);
202            return -1;
203          }
204
205          strncpy (path, file, i);
206          path[i] = '\0';
207
208          if (rtems_rootfs_mkdir (path, MKDIR_MODE))
209            return -1;
210          break;
211        }
212        i--;
213      }
214
215      if ((fd = open (file, O_CREAT | O_APPEND | O_WRONLY, omode)) < 0)
216      {
217        printf ("root fs, cannot create file `%s' : %s\n",
218                file, strerror (errno));
219        return -1;
220      }
221    }
222  }
223
224  if (fd < 0)
225  {
226    if ((fd = open (file, O_APPEND | O_WRONLY)) < 0)
227    {
228      printf ("root fs, cannot open file `%s' : %s\n",
229              file, strerror (errno));
230      return -1;
231    }
232  }
233
234  for (i = 0; i < line_cnt; i++)
235  {
236    int len = strlen (lines[i]);
237
238    if (len)
239    {
240      if (write (fd, lines[i], strlen (lines[i])) < 0)
241      {
242        close (fd);
243        printf ("root fs, cannot write to `%s' : %s\n",
244                file, strerror (errno));
245        return -1;
246      }
247    }
248  }
249
250  return close (fd);
251}
252
253/*
254 * Write hosts record.
255 */
256
257int
258rtems_rootfs_append_host_rec (unsigned long cip,
259                              const char    *cname,
260                              const char    *dname)
261{
262  char           buf[128];
263  char           *bufp = buf;
264  const char     *bufl[1];
265  struct in_addr ip;
266
267  ip.s_addr = cip;
268
269  if (cname && strlen (cname))
270  {
271    snprintf (bufp, sizeof (buf), "%s\t\t%s", inet_ntoa (ip), cname);
272    bufp += strlen (buf);
273
274    if (dname && strlen (dname))
275    {
276      snprintf (bufp, sizeof (buf), "\t\t%s.%s", cname, dname);
277      bufp += strlen (buf);
278    }
279
280    strcat (buf, "\n");
281
282    bufl[0] = buf;
283
284    if (rtems_rootfs_file_append ("/etc/hosts", MKFILE_MODE, 1, bufl) < 0)
285      return -1;
286  }
287  else
288  {
289    printf ("rootfs hosts rec append, no cname supplied\n");
290    return -1;
291  }
292
293  return 0;
294}
295
296/*
297 * Create a root file system.
298 */
299
300int
301rtems_create_root_fs ()
302{
303  const char *lines[1];
304  int        i;
305
306  /*
307   * Create the directories.
308   */
309
310  for (i = 0;
311       i < (sizeof (default_directories) / sizeof (rtems_rootfs_dir_table));
312       i++)
313    if (rtems_rootfs_mkdir (default_directories[i].name,
314                            default_directories[i].mode))
315      return -1;
316
317  /*
318   * The TCP/IP stack likes this one. If DNS does not work
319   * use the host file.
320   */
321
322  lines[0] = "hosts,bind\n";
323
324  if (rtems_rootfs_file_append ("/etc/host.conf", MKFILE_MODE, 1, lines))
325    return -1;
326
327  /*
328   * Create a `/etc/hosts' file.
329   */
330
331  if (rtems_rootfs_append_host_rec (0x7f000001, "localhost", "localdomain"))
332    return -1;
333
334  return 0;
335}
Note: See TracBrowser for help on using the repository browser.