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

4.104.115
Last change on this file since cb4e992 was cb4e992, checked in by Joel Sherrill <joel.sherrill@…>, on 01/19/10 at 19:31:00

2010-01-19 Joel Sherrill <joel.sherrill@…>

  • libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_creat.c, libfs/src/imfs/imfs_initsupp.c, libfs/src/imfs/imfs_link.c, libfs/src/imfs/imfs_load_tar.c, libfs/src/imfs/imfs_mknod.c, libfs/src/imfs/imfs_symlink.c: Create special helper method for creating the j-node for the root directory. This lets us assume that every j-node created otherwise has a parent node.
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2010.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 * $Id$
10 */
11
12#if HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16/*
17 * This file implements the "mount" procedure for tar-based IMFS
18 * extensions.  The TAR is not actually mounted under the IMFS.
19 * Directories from the TAR file are created as usual in the IMFS.
20 * File entries are created as IMFS_LINEAR_FILE nodes with their nods
21 * pointing to addresses in the TAR image.
22 */
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27
28#include <string.h>
29
30#include <rtems.h>
31#include <rtems/libio_.h>
32#include <rtems/imfs.h>
33#include <rtems/untar.h>
34#include <rtems/tar.h>
35
36/*
37 * TAR file format:
38 *
39 *   Offset   Length   Contents
40 *     0    100 bytes  File name ('\0' terminated, 99 maxmum length)
41 *   100      8 bytes  File mode (in octal ascii)
42 *   108      8 bytes  User ID (in octal ascii)
43 *   116      8 bytes  Group ID (in octal ascii)
44 *   124     12 bytes  File size (s) (in octal ascii)
45 *   136     12 bytes  Modify time (in octal ascii)
46 *   148      8 bytes  Header checksum (in octal ascii)
47 *   156      1 bytes  Link flag
48 *   157    100 bytes  Linkname ('\0' terminated, 99 maxmum length)
49 *   257      8 bytes  Magic ("ustar  \0")
50 *   265     32 bytes  User name ('\0' terminated, 31 maxmum length)
51 *   297     32 bytes  Group name ('\0' terminated, 31 maxmum length)
52 *   329      8 bytes  Major device ID (in octal ascii)
53 *   337      8 bytes  Minor device ID (in octal ascii)
54 *   345    167 bytes  Padding
55 *   512   (s+p)bytes  File contents (s+p) := (((s) + 511) & ~511),
56 *                     round up to 512 bytes
57 *
58 *   Checksum:
59 *   int i, sum;
60 *   char* header = tar_header_pointer;
61 *   sum = 0;
62 *   for(i = 0; i < 512; i++)
63 *       sum += 0xFF & header[i];
64 */
65
66#define MAX_NAME_FIELD_SIZE      99
67
68#define MIN(a,b)   ((a)>(b)?(b):(a))
69
70/*
71 * rtems_tarfs_load
72 *
73 * Here we create the mountpoint directory and load the tarfs at
74 * that node.  Once the IMFS has been mounted, we work through the
75 * tar image and perform as follows:
76 *  - For directories, simply call mkdir().  The IMFS creates nodes as
77 *    needed.
78 *  - For files, we make our own calls to IMFS eval_for_make and
79 *    create_node.
80 */
81int rtems_tarfs_load(
82  char    *mountpoint,
83  uint8_t *tar_image,
84  size_t   tar_size
85)
86{
87   rtems_filesystem_location_info_t  root_loc;
88   rtems_filesystem_location_info_t  loc;
89   const char                       *hdr_ptr;
90   char                             filename[100];
91   char                             full_filename[256];
92   int                              hdr_chksum;
93   unsigned char                    linkflag;
94   unsigned long                    file_size;
95   unsigned long                    file_mode;
96   int                              offset;
97   unsigned long                    nblocks;
98   IMFS_jnode_t                    *node;
99   int                              status;
100
101   status = rtems_filesystem_evaluate_path(
102      mountpoint,
103      strlen(mountpoint),
104      0,
105      &root_loc,
106      0
107   );
108   if (status != 0)
109      return -1;
110
111   if (root_loc.ops != &IMFS_ops)
112      return -1;
113
114   /*
115    * Create an IMFS node structure pointing to tar image memory.
116    */
117   offset = 0;
118   while (1) {
119    if (offset + 512 > tar_size)
120      break;
121
122    /*
123     * Read a header.
124     */
125    hdr_ptr = (char *) &tar_image[offset];
126    offset += 512;
127    if (strncmp(&hdr_ptr[257], "ustar  ", 7))
128      break;
129
130    strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
131    filename[MAX_NAME_FIELD_SIZE] = '\0';
132
133    linkflag   = hdr_ptr[156];
134    file_mode  = _rtems_octal2ulong(&hdr_ptr[100], 8);
135    file_size  = _rtems_octal2ulong(&hdr_ptr[124], 12);
136    hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);
137
138    if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
139      break;
140
141    /*
142     * Generate an IMFS node depending on the file type.
143     * - For directories, just create directories as usual.  IMFS
144     *   will take care of the rest.
145     * - For files, create a file node with special tarfs properties.
146     */
147    if (linkflag == DIRTYPE) {
148      strcpy(full_filename, mountpoint);
149      if (full_filename[strlen(full_filename)-1] != '/')
150        strcat(full_filename, "/");
151      strcat(full_filename, filename);
152      mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
153    }
154    /*
155     * Create a LINEAR_FILE node
156     *
157     *  NOTE: Coverity Id 20 reports this as a leak.
158     *        While technically not a leak, it indicated that
159     *        IMFS_create_node was ONLY passed a NULL when we created the
160     *        root node.  We added a new IMFS_create_root_node() so this
161     *        path no longer existed.  The result was simpler code which
162     *        should not have this path.
163     */
164    else if (linkflag == REGTYPE) {
165      const char  *name;
166
167      loc = root_loc;
168      if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) {
169        node = IMFS_create_node(
170          &loc,
171          IMFS_LINEAR_FILE, (char *)name,
172          (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
173          NULL
174        );
175        node->info.linearfile.size   = file_size;
176        node->info.linearfile.direct = &tar_image[offset];
177      }
178
179      nblocks = (((file_size) + 511) & ~511) / 512;
180      offset += 512 * nblocks;
181    }
182  }
183  return status;
184}
185
Note: See TracBrowser for help on using the repository browser.