source: rtems/cpukit/libfs/src/imfs/imfs_load_tar.c @ f785492

4.115
Last change on this file since f785492 was a9df916, checked in by Sebastian Huber <sebastian.huber@…>, on 02/08/15 at 18:43:09

IMFS: Add fine grained configuration

Remove miniIMFS. Statically initialize the root IMFS.

Add configuration options to disable individual
features of the root IMFS, e.g.

o CONFIGURE_IMFS_DISABLE_CHOWN,
o CONFIGURE_IMFS_DISABLE_FCHMOD,
o CONFIGURE_IMFS_DISABLE_LINK,
o CONFIGURE_IMFS_DISABLE_MKNOD,
o CONFIGURE_IMFS_DISABLE_MOUNT,
o CONFIGURE_IMFS_DISABLE_READLINK,
o CONFIGURE_IMFS_DISABLE_RENAME,
o CONFIGURE_IMFS_DISABLE_RMNOD,
o CONFIGURE_IMFS_DISABLE_SYMLINK,
o CONFIGURE_IMFS_DISABLE_UNMOUNT, and
o CONFIGURE_IMFS_DISABLE_UTIME.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/**
2 * @file
3 *
4 * @brief RTEMS Load Tarfs
5 * @ingroup IMFS
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2010.
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 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include "imfs.h"
22
23#include <sys/param.h>
24#include <sys/stat.h>
25#include <string.h>
26#include <tar.h>
27#include <unistd.h>
28
29#include <rtems/untar.h>
30
31#define MAX_NAME_FIELD_SIZE      99
32
33int rtems_tarfs_load(
34  const char *mountpoint,
35  uint8_t *tar_image,
36  size_t tar_size
37)
38{
39   const char                       *hdr_ptr;
40   char                             filename[100];
41   char                             full_filename[256];
42   int                              hdr_chksum;
43   unsigned char                    linkflag;
44   unsigned long                    file_size;
45   unsigned long                    file_mode;
46   int                              offset;
47   unsigned long                    nblocks;
48   int rv = 0;
49   int eval_flags = RTEMS_FS_FOLLOW_LINK;
50   rtems_filesystem_eval_path_context_t ctx;
51   rtems_filesystem_location_info_t rootloc;
52   rtems_filesystem_location_info_t *currentloc =
53     rtems_filesystem_eval_path_start( &ctx, mountpoint, eval_flags );
54
55   rtems_filesystem_eval_path_extract_currentloc( &ctx, &rootloc );
56   rtems_filesystem_eval_path_set_flags(
57     &ctx,
58     RTEMS_FS_MAKE | RTEMS_FS_EXCLUSIVE
59   );
60
61   if ( !IMFS_is_imfs_instance( &rootloc ) ) {
62     rv = -1;
63   }
64
65   /*
66    * Create an IMFS node structure pointing to tar image memory.
67    */
68   offset = 0;
69   while ( rv == 0 ) {
70    if (offset + 512 > tar_size)
71      break;
72
73    /*
74     * Read a header.
75     */
76    hdr_ptr = (char *) &tar_image[offset];
77    offset += 512;
78    if (strncmp(&hdr_ptr[257], "ustar", 5))
79      break;
80
81    strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
82    filename[MAX_NAME_FIELD_SIZE] = '\0';
83
84    linkflag   = hdr_ptr[156];
85    file_mode  = _rtems_octal2ulong(&hdr_ptr[100], 8);
86    file_size  = _rtems_octal2ulong(&hdr_ptr[124], 12);
87    hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);
88
89    if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
90      break;
91
92    /*
93     * Generate an IMFS node depending on the file type.
94     * - For directories, just create directories as usual.  IMFS
95     *   will take care of the rest.
96     * - For symbolic links, create as usual
97     * - For files, create a file node with special tarfs properties.
98     */
99    if (linkflag == DIRTYPE) {
100      int len;
101      strncpy(full_filename, mountpoint, 255);
102      if (full_filename[(len=strlen(full_filename))-1] != '/')
103        strcat(full_filename, "/");
104      ++len;
105      strncat(full_filename, filename, 256-len-1);
106      rv = mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
107    }
108    /*
109     * Create a LINEAR_FILE node
110     */
111    else if (linkflag == REGTYPE) {
112      rtems_filesystem_location_free( currentloc );
113      rtems_filesystem_location_clone( currentloc, &rootloc );
114      rtems_filesystem_eval_path_set_path(
115        &ctx,
116        filename,
117        strlen( filename )
118      );
119      rtems_filesystem_eval_path_continue( &ctx );
120
121      if ( !rtems_filesystem_location_is_null( currentloc ) ) {
122        IMFS_linearfile_t *linfile = (IMFS_linearfile_t *)
123          IMFS_create_node(
124            currentloc,
125            &IMFS_node_control_linfile,
126            sizeof( IMFS_file_t ),
127            rtems_filesystem_eval_path_get_token( &ctx ),
128            rtems_filesystem_eval_path_get_tokenlen( &ctx ),
129            (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
130            NULL
131          );
132
133        if ( linfile != NULL ) {
134          linfile->File.size = file_size;
135          linfile->direct    = &tar_image[offset];
136        }
137      }
138
139      nblocks = (((file_size) + 511) & ~511) / 512;
140      offset += 512 * nblocks;
141    }
142    /*
143     * Create a symbolic link
144     */
145    else if (linkflag == SYMTYPE) {
146      const char *linkto = hdr_ptr + 157;
147      int len;
148
149      strncpy(full_filename, mountpoint, 255);
150      if (full_filename[(len=strlen(full_filename))-1] != '/')
151        strcat(full_filename, "/");
152      ++len;
153      strncat(full_filename, filename, 256-len-1);
154
155      rv = symlink(linkto, full_filename);
156    }
157  }
158
159  rtems_filesystem_location_free( &rootloc );
160  rtems_filesystem_eval_path_cleanup( &ctx );
161
162  return rv;
163}
164
Note: See TracBrowser for help on using the repository browser.