File: tarfile.cpp

package info (click to toggle)
postbooks 4.10.0-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 112,660 kB
  • ctags: 22,890
  • sloc: cpp: 310,358; sh: 607; xml: 214; python: 140; awk: 104; makefile: 50
file content (115 lines) | stat: -rw-r--r-- 3,324 bytes parent folder | download | duplicates (3)
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
/*
 * This file is part of the xTuple ERP: PostBooks Edition, a free and
 * open source Enterprise Resource Planning software suite,
 * Copyright (c) 1999-2016 by OpenMFG LLC, d/b/a xTuple.
 * It is licensed to you under the Common Public Attribution License
 * version 1.0, the full text of which (including xTuple-specific Exhibits)
 * is available at www.xtuple.com/CPAL.  By using this software, you agree
 * to be bound by its terms.
 */

#include "tarfile.h"

#include <qtextstream.h>
#include <qbuffer.h>

struct tarHeaderBlock {
    char name[100];     // name of file
    char mode[8];       // file mode
    char uid[8];        // owner user ID
    char gid[8];        // owner group ID
    char size[12];      // length of file in bytes
    char mtime[12];     // modified time of file
    char chksum[8];     // header checksum
    char typeflag;      // see type constants
    char linkname[100]; // name of linked file
    char magic[8];      // "ustar  " + null terminator
    char uname[32];     // owner user name
    char gname[32];     // owner group name
    char devmajor[8];   // device major number
    char devminor[8];   // device minor number
    char prefix[155];   // prefix for file names longer than 100 bytes
    char filler[12];    // filler to make header even 512 bytes
};

const char TYPE_REGULAR_ALT = '\0'; // old compatible flag for regular file
const char TYPE_REGULAR     = '0';  // regular file
const char TYPE_LINK        = '1';  // link to another file in archive
const char TYPE_SYMLINK     = '2';  // Symbolic link
const char TYPE_CHAR        = '3';  // Character special device
const char TYPE_BLOCK       = '4';  // Block special device
const char TYPE_DIR         = '5';  // Directory
const char TYPE_FIFO        = '6';  // FIFO special file
const char TYPE_CONTIGUOS   = '7';  // RESERVERED/Contiguous file


TarFile::TarFile(const QByteArray & bytes)
{
  Q_UNUSED(TYPE_LINK);
  Q_UNUSED(TYPE_SYMLINK);
  Q_UNUSED(TYPE_CHAR);
  Q_UNUSED(TYPE_BLOCK);
  Q_UNUSED(TYPE_DIR);
  Q_UNUSED(TYPE_FIFO);
  Q_UNUSED(TYPE_CONTIGUOS);
  _valid = false;

  QByteArray localBytes(bytes);
  QBuffer fin(&localBytes);
  if(!fin.open(QIODevice::ReadOnly))
    return;

  bool valid = false;
  long size = 0;
  long blocks = 0;
  char block[512];
  QString name, str;

  while(!fin.atEnd())
  {
    tarHeaderBlock head;
    fin.read((char*)&head, sizeof(head));

    if(head.name[0] == '\0' && head.size[0] == '\0' && head.typeflag == '\0')
      continue;

    QString magic(head.magic);
    if(magic.trimmed() != "ustar")
      return;

    name = QString(head.name);
    str = QString(head.size);
    str.remove(sizeof head.size, sizeof head);
    size = str.toLong(&valid, 8);

    if(head.typeflag == TYPE_REGULAR_ALT)
      head.typeflag = TYPE_REGULAR;

    blocks = (size + 511) / 512;

    if(head.typeflag == TYPE_REGULAR)
    {
      QByteArray mybytes;
      QBuffer fout(&mybytes);
      fout.open(QIODevice::WriteOnly);
      for(int i = 0; i < blocks; i++)
      {
        fin.read(&block[0], 512);
        fout.write(&block[0], qMin(size,512L));
        size -= 512;
      }
      fout.close();
      _list.insert(name, mybytes);
    }
    else
    {
      for(int i = 0; i < blocks; i++)
        fin.read(&block[0], 512);
    }
  }
  _valid = true;
}

TarFile::~TarFile()
{
}