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

4.104.114.84.95
Last change on this file since b2b143f4 was b2b143f4, checked in by Joel Sherrill <joel.sherrill@…>, on 03/05/04 at 17:58:51

2004-03-05 Joel Sherrill <joel@…>

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