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
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#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.