Changeset 1a8fe67a in rtems


Ignore:
Timestamp:
Jul 13, 2016, 7:22:35 AM (3 years ago)
Author:
Alexander Krutwig <alexander.krutwig@…>
Branches:
master
Children:
6a174c02
Parents:
c1b815ab
git-author:
Alexander Krutwig <alexander.krutwig@…> (07/13/16 07:22:35)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/26/16 08:00:04)
Message:

Add Untar_FromChunk_Print() + Test

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/untar/untar.c

    rc1b815ab r1a8fe67a  
    3737#include <rtems/untar.h>
    3838#include <rtems/bspIo.h>
    39 
    4039
    4140/*
     
    542541}
    543542
     543
     544void Untar_ChunkContext_Init(Untar_ChunkContext *context)
     545{
     546  context->state = UNTAR_CHUNK_HEADER;
     547  context->done_bytes = 0;
     548  context->out_fd = -1;
     549}
     550
     551int Untar_FromChunk_Print(
     552  Untar_ChunkContext *context,
     553  void *chunk,
     554  size_t chunk_size,
     555  const rtems_printer* printer
     556)
     557{
     558  char *buf;
     559  size_t done;
     560  size_t todo;
     561  size_t remaining;
     562  size_t consume;
     563  int retval;
     564  unsigned char linkflag;
     565
     566  buf = chunk;
     567  done = 0;
     568  todo = chunk_size;
     569
     570  while (todo > 0) {
     571    switch (context->state) {
     572      case UNTAR_CHUNK_HEADER:
     573        remaining = 512 - context->done_bytes;
     574        consume = MIN(remaining, todo);
     575        memcpy(&context->header[context->done_bytes], &buf[done], consume);
     576        context->done_bytes += consume;
     577
     578        if (context->done_bytes == 512) {
     579          retval = Untar_ProcessHeader(
     580            &context->header[0],
     581            &context->fname[0],
     582            &context->todo_bytes,
     583            &context->todo_blocks,
     584            &linkflag,
     585            printer
     586          );
     587
     588          if (retval != UNTAR_SUCCESSFUL) {
     589            context->state = UNTAR_CHUNK_ERROR;
     590            return retval;
     591          }
     592
     593          if (linkflag == REGTYPE) {
     594            context->out_fd = creat(&context->fname[0], 0644);
     595
     596            if (context->out_fd >= 0) {
     597              context->state = UNTAR_CHUNK_WRITE;
     598              context->done_bytes = 0;
     599            } else {
     600              context->state = UNTAR_CHUNK_SKIP;
     601              context->todo_bytes = 512 * context->todo_blocks;
     602              context->done_bytes = 0;
     603            }
     604          } else {
     605              context->done_bytes = 0;
     606          }
     607        }
     608
     609        break;
     610      case UNTAR_CHUNK_SKIP:
     611        remaining = context->todo_bytes - context->done_bytes;
     612        consume = MIN(remaining, todo);
     613        context->done_bytes += consume;
     614
     615        if (context->done_bytes == context->todo_bytes) {
     616          context->state = UNTAR_CHUNK_HEADER;
     617          context->done_bytes = 0;
     618        }
     619
     620        break;
     621      case UNTAR_CHUNK_WRITE:
     622        remaining = context->todo_bytes - context->done_bytes;
     623        consume = MIN(remaining, todo);
     624        write(context->out_fd, &buf[done], consume);
     625        context->done_bytes += consume;
     626
     627        if (context->done_bytes == context->todo_bytes) {
     628          close(context->out_fd);
     629          context->out_fd = -1;
     630          context->state = UNTAR_CHUNK_SKIP;
     631          context->todo_bytes = 512 * context->todo_blocks - context->todo_bytes;
     632          context->done_bytes = 0;
     633        }
     634
     635        break;
     636      default:
     637        return UNTAR_FAIL;
     638    }
     639
     640    done += consume;
     641    todo -= consume;
     642  }
     643
     644  return UNTAR_SUCCESSFUL;
     645}
     646
    544647/*
    545648 * Function: Untar_FromFile
  • cpukit/libmisc/untar/untar.h

    rc1b815ab r1a8fe67a  
    4545int Untar_FromFile_Print(const char *tar_name, const rtems_printer* printer);
    4646
     47typedef struct {
     48  /**
     49   * @brief Current context state.
     50   */
     51  enum {
     52    UNTAR_CHUNK_HEADER,
     53    UNTAR_CHUNK_SKIP,
     54    UNTAR_CHUNK_WRITE,
     55    UNTAR_CHUNK_ERROR
     56  } state;
     57
     58  /**
     59   * @brief Header buffer.
     60   */
     61  char header[512];
     62
     63  /**
     64   * @brief Name buffer.
     65   */
     66  char fname[100];
     67
     68  /**
     69   * @brief Number of bytes of overall length are already processed.
     70   */
     71  size_t done_bytes;
     72
     73  /**
     74   * @brief Overall amount of bytes to be processed.
     75   */
     76  long unsigned todo_bytes;
     77
     78  /**
     79   * @brief Overall amount of blocks to be processed.
     80   */
     81  unsigned long todo_blocks;
     82
     83  /**
     84   * @brief File descriptor of output file.
     85   */
     86  int out_fd;
     87} Untar_ChunkContext;
     88
     89typedef struct {
     90  /**
     91   * @brief Instance of Chunk Context needed for tar decompression.
     92   */
     93  Untar_ChunkContext base;
     94
     95  /**
     96   * @brief Current zlib context.
     97   */
     98  z_stream strm;
     99
     100  /**
     101   * @brief Buffer that contains the inflated data.
     102   */
     103  void *inflateBuffer;
     104
     105  /**
     106   * @brief Size of buffer that contains the inflated data.
     107   */
     108  size_t inflateBufferSize;
     109
     110} Untar_GzChunkContext;
     111
     112/**
     113 * @brief Initializes the Untar_ChunkContext files out of a part of a block of
     114 * memory.
     115 *
     116 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
     117 */
     118void Untar_ChunkContext_Init(Untar_ChunkContext *context);
     119
     120/*
     121 * @brief Rips links, directories and files out of a part of a block of memory.
     122 *
     123 * @param Untar_ChunkContext *context [in] Pointer to a context structure.
     124 * @param void *chunk [in] Pointer to a chunk of a TAR buffer.
     125 * @param size_t chunk_size [in] Length of the chunk of a TAR buffer.
     126 *
     127 * @retval UNTAR_SUCCESSFUL (0)    on successful completion.
     128 * @retval UNTAR_FAIL              for a faulty step within the process.
     129 * @retval UNTAR_INVALID_CHECKSUM  for an invalid header checksum.
     130 * @retval UNTAR_INVALID_HEADER    for an invalid header.
     131 */
     132
     133int Untar_FromChunk_Print(
     134  Untar_ChunkContext *context,
     135  void *chunk,
     136  size_t chunk_size,
     137  const rtems_printer* printer
     138);
     139
    47140/**************************************************************************
    48141 * This converts octal ASCII number representations into an
  • testsuites/libtests/tar01/init.c

    rc1b815ab r1a8fe67a  
    3232void test_untar_from_memory(void);
    3333void test_untar_from_file(void);
     34void test_untar_chunks_from_memory(void);
    3435
    3536#define TARFILE_START initial_filesystem_tar
     
    107108}
    108109
     110void test_untar_chunks_from_memory(void)
     111{
     112  rtems_status_code sc;
     113  rtems_printer     printer;
     114  int rv;
     115  Untar_ChunkContext ctx;
     116  unsigned long counter = 0;
     117  char *buffer = (char *)TARFILE_START;
     118  size_t buflen = TARFILE_SIZE;
     119
     120  rtems_print_printer_printf(&printer);
     121
     122  /* make a directory to untar it into */
     123  rv = mkdir( "/dest2", 0777 );
     124  rtems_test_assert( rv == 0 );
     125
     126  rv = chdir( "/dest2" );
     127  rtems_test_assert( rv == 0 );
     128
     129  printf( "Untaring chunks from memory - " );
     130  Untar_ChunkContext_Init(&ctx);
     131  do {
     132    sc = Untar_FromChunk_Print(&ctx, &buffer[counter], (size_t)1 , &printer);
     133    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     134    counter ++;
     135  } while (counter < buflen);
     136  printf("successful\n");
     137
     138  /******************/
     139  printf( "========= /dest2/home/test_file =========\n" );
     140  test_cat( "/dest2/home/test_file", 0, 0 );
     141
     142  /******************/
     143  printf( "========= /dest2/symlink =========\n" );
     144  test_cat( "/dest2/symlink", 0, 0 );
     145
     146}
     147
    109148rtems_task Init(
    110149  rtems_task_argument ignored
     
    116155  puts( "" );
    117156  test_untar_from_file();
     157  puts( "" );
     158  test_untar_chunks_from_memory();
    118159
    119160  TEST_END();
  • testsuites/libtests/tar01/tar01.scn

    rc1b815ab r1a8fe67a  
    2020initial tar image.
    2121
     22
     23Untaring chunks from memory - untar: dir: home
     24untar: file: home/test_file (73)
     25successful
     26========= /dest2/home/test_file =========
     27(0)This is a test of loading an RTEMS filesystem from an
     28initial tar image.
     29
     30========= /dest2/symlink =========
     31(0)This is a test of loading an RTEMS filesystem from an
     32initial tar image.
     33
    2234*** END OF TAR01 TEST ***
Note: See TracChangeset for help on using the changeset viewer.