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

4.104.115
Last change on this file since 9ba0e55 was 9ba0e55, checked in by Joel Sherrill <joel.sherrill@…>, on 01/18/10 at 23:39:31

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

Coverity Id 19
Coverity Id 20
Coverity Id 21

  • libfs/src/imfs/imfs_link.c, libfs/src/imfs/imfs_load_tar.c, libfs/src/imfs/imfs_mknod.c: Add comment to explain allocation is for life of file, not scope of method.
  • Property mode set to 100644
File size: 5.2 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(mountpoint, strlen(mountpoint),
102                                           0, &root_loc, 0);
103   if (status != 0)
104      return(-1);
105
106   if (root_loc.ops != &IMFS_ops)
107      return -1;
108
109   /*
110    * Create an IMFS node structure pointing to tar image memory.
111    */
112   offset = 0;
113   while (1) {
114      if (offset + 512 > tar_size)
115         break;
116
117      /*
118       * Read a header.
119       */
120      hdr_ptr = (char *) &tar_image[offset];
121      offset += 512;
122      if (strncmp(&hdr_ptr[257], "ustar  ", 7))
123         break;
124
125      strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);
126      filename[MAX_NAME_FIELD_SIZE] = '\0';
127
128      linkflag   = hdr_ptr[156];
129      file_mode  = _rtems_octal2ulong(&hdr_ptr[100], 8);
130      file_size  = _rtems_octal2ulong(&hdr_ptr[124], 12);
131      hdr_chksum = _rtems_octal2ulong(&hdr_ptr[148], 8);
132
133      if (_rtems_tar_header_checksum(hdr_ptr) != hdr_chksum)
134         break;
135
136      /*
137       * Generate an IMFS node depending on the file type.
138       * - For directories, just create directories as usual.  IMFS
139       *   will take care of the rest.
140       * - For files, create a file node with special tarfs properties.
141       */
142      if (linkflag == DIRTYPE) {
143         strcpy(full_filename, mountpoint);
144         if (full_filename[strlen(full_filename)-1] != '/')
145            strcat(full_filename, "/");
146         strcat(full_filename, filename);
147         mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);
148      }
149      /*
150       * Create a LINEAR_FILE node
151       *
152       * NOTE: Coverity thinks this is a resource leak since a node
153       *       is created but never deleted.  The scope of the allocation
154       *       is that of a file -- not this method.  Coverity Id 20.
155       */
156      else if (linkflag == REGTYPE) {
157         const char  *name;
158
159         loc = root_loc;
160         if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) {
161            node = IMFS_create_node(&loc,
162                        IMFS_LINEAR_FILE, (char *)name,
163                        (file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
164                        NULL);
165            node->info.linearfile.size   = file_size;
166            node->info.linearfile.direct = &tar_image[offset];
167         }
168
169         nblocks = (((file_size) + 511) & ~511) / 512;
170         offset += 512 * nblocks;
171      }
172   }
173
174   return status;
175}
176
Note: See TracBrowser for help on using the repository browser.