source: rtems/cpukit/libnetworking/rtems/mkrootfs.c @ eacd092c

Last change on this file since eacd092c was eacd092c, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 18:47:07

2003-09-04 Joel Sherrill <joel@…>

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