summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/untar/untar.h
blob: bc0a97c1035802de7e1ea5d277e9075d5156b9be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/**
 * @file
 *
 * @brief Untar an Image
 *
 * This file defines the interface to methods which can untar an image.
 */

/*
 *  Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_UNTAR_H
#define _RTEMS_UNTAR_H

#include <stdbool.h>
#include <stddef.h>
#include <tar.h>
#include <zlib.h>
#include <xz.h>

#include <rtems/print.h>

/**
 *  @defgroup libmisc_untar_img Untar Image
 *
 *  @ingroup libmisc
 */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif

#define UNTAR_SUCCESSFUL         0
#define UNTAR_FAIL               1
#define UNTAR_INVALID_CHECKSUM   2
#define UNTAR_INVALID_HEADER     3

#define UNTAR_GZ_INFLATE_FAILED 4
#define UNTAR_GZ_INFLATE_END_FAILED 5

int Untar_FromMemory(void *tar_buf, size_t size);
int Untar_FromMemory_Print(void *tar_buf, size_t size, const rtems_printer* printer);
int Untar_FromFile(const char *tar_name);
int Untar_FromFile_Print(const char *tar_name, const rtems_printer* printer);

typedef struct {
  /**
   * @brief Current context state.
   */
  enum {
    UNTAR_CHUNK_HEADER,
    UNTAR_CHUNK_SKIP,
    UNTAR_CHUNK_WRITE,
    UNTAR_CHUNK_ERROR
  } state;

  /**
   * @brief Header buffer.
   */
  char header[512];

  /**
   * @brief Name buffer.
   */
  char fname[100];

  /**
   * @brief Number of bytes of overall length are already processed.
   */
  size_t done_bytes;

  /**
   * @brief Mode of the file.
   */
  unsigned long mode;

  /**
   * @brief Overall amount of bytes to be processed.
   */
  unsigned long todo_bytes;

  /**
   * @brief Overall amount of blocks to be processed.
   */
  unsigned long todo_blocks;

  /**
   * @brief File descriptor of output file.
   */
  int out_fd;
} Untar_ChunkContext;

typedef struct {
  /**
   * @brief Instance of Chunk Context needed for tar decompression.
   */
  Untar_ChunkContext base;

  /**
   * @brief Current zlib context.
   */
  z_stream strm;

  /**
   * @brief Buffer that contains the inflated data.
   */
  void *inflateBuffer;

  /**
   * @brief Size of buffer that contains the inflated data.
   */
  size_t inflateBufferSize;

} Untar_GzChunkContext;

typedef struct {
  /**
   * @brief Instance of Chunk Context needed for tar decompression.
   */
  Untar_ChunkContext base;

  /**
   * @brief Xz context.
   */
  struct xz_dec* strm;

  /**
   * @brief Xz buffer.
   */
  struct xz_buf buf;

  /**
   * @brief Buffer that contains the inflated data.
   */
  void *inflateBuffer;

  /**
   * @brief Size of buffer that contains the inflated data.
   */
  size_t inflateBufferSize;

} Untar_XzChunkContext;

/**
 * @brief Initializes the Untar_ChunkContext files out of a part of a block of
 * memory.
 *
 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
 */
void Untar_ChunkContext_Init(Untar_ChunkContext *context);

/*
 * @brief Rips links, directories and files out of a part of a block of memory.
 *
 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
 * @param void *chunk [in] Pointer to a chunk of a TAR buffer.
 * @param size_t chunk_size [in] Length of the chunk of a TAR buffer.
 *
 * @retval UNTAR_SUCCESSFUL (0)    on successful completion.
 * @retval UNTAR_FAIL              for a faulty step within the process.
 * @retval UNTAR_INVALID_CHECKSUM  for an invalid header checksum.
 * @retval UNTAR_INVALID_HEADER    for an invalid header.
 */

int Untar_FromChunk_Print(
  Untar_ChunkContext *context,
  void *chunk,
  size_t chunk_size,
  const rtems_printer* printer
);

/**
 * @brief Initializes the Untar_ChunkGzContext.
 *
 * @param Untar_ChunkGzContext *context [in] Pointer to a context structure.
 * @param void *inflateBuffer [in] Pointer to a context structure.
 * @param size_t inflateBufferSize [in] Size of inflateBuffer.
 */
int Untar_GzChunkContext_Init(
  Untar_GzChunkContext *ctx,
  void *inflateBuffer,
  size_t inflateBufferSize
);

/*
 * @brief Untars a GZ compressed POSIX TAR file.
 *
 * This is a subroutine used to rip links, directories, and
 * files out of a tar.gz/tgz file.
 *
 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
 * @param ssize buflen [in] Size of valid bytes in input buffer.
 * @param z_stream *strm [in] Pointer to the current zlib context.
 */
int Untar_FromGzChunk_Print(
  Untar_GzChunkContext *ctx,
  void *chunk,
  size_t chunk_size,
  const rtems_printer* printer
);

/**
 * @brief Initializes the Untar_ChunkXzContext.
 *
 * @param Untar_ChunkXzContext *context [in] Pointer to a context structure.
 * @param enum xz_mode mode [in] Dictionary mode.
 * @param uint32_t dict_max [in] Maximum size of dictionary.
 * @param void *inflateBuffer [in] Pointer to a context structure.
 * @param size_t inflateBufferSize [in] Size of inflateBuffer.
 */
int Untar_XzChunkContext_Init(
  Untar_XzChunkContext *ctx,
  enum xz_mode mode,
  uint32_t dict_max,
  void *inflateBuffer,
  size_t inflateBufferSize
);

/*
 * @brief Untars a XZ compressed POSIX TAR file.
 *
 * This is a subroutine used to rip links, directories, and
 * files out of a tar.gz/tgz file.
 *
 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
 * @param ssize buflen [in] Size of valid bytes in input buffer.
 * @param z_stream *strm [in] Pointer to the current zlib context.
 */
int Untar_FromXzChunk_Print(
  Untar_XzChunkContext *ctx,
  const void *chunk,
  size_t chunk_size,
  const rtems_printer* printer
);

/**************************************************************************
 * This converts octal ASCII number representations into an
 * unsigned long.  Only support 32-bit numbers for now.
 *************************************************************************/
extern unsigned long
_rtems_octal2ulong(const char *octascii, size_t len);

/************************************************************************
 * Compute the TAR checksum and check with the value in
 * the archive.  The checksum is computed over the entire
 * header, but the checksum field is substituted with blanks.
 ************************************************************************/
extern int
_rtems_tar_header_checksum(const char *bufr);

#ifdef __cplusplus
}
#endif
/**@}*/
#endif  /* _RTEMS_UNTAR_H */