-
Notifications
You must be signed in to change notification settings - Fork 7
/
tarball_traversal.cc
108 lines (87 loc) · 2.32 KB
/
tarball_traversal.cc
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
/* Copyright (c) 2011 Akamai Technologies, Inc. */
#include "system.hh"
#include <archive.h>
#include <archive_entry.h>
#include "cgen.h"
#include "log.h"
#include "encode.h"
#include "decode.h"
#include "decider.h"
#include "scanner_mode.h"
#include "config.h"
#include "counter.h"
#include "traversal.h"
#include "tarball_traversal.h"
#include "scanner.h"
#include "scannable.h"
#include "tarball_scannable.h"
TarballTraversal::TarballTraversal()
:
archive_name_(),
archive_(NULL),
entry_(NULL)
{}
TarballTraversal::~TarballTraversal() {}
int TarballTraversal::Init(StringPiece archive_name,
struct archive* archive,
Scanner* scanner)
{
CHK(archive_name.empty(), "empty archive name", out_error)
archive_name_ = archive_name;
CHK(archive == NULL, "null archive", out_error);
archive_ = archive;
CHK(scanner == NULL, "null scanner", out_error);
scanner_ = scanner;
return 0;
out_error:
return 1;
}
int TarballTraversal::go(bool* done)
{
int ret;
ssize_t len;
StringPiece bufp;
TarballScannable sc_tb;
ret = archive_read_next_header(archive_, &entry_);
if (ret == ARCHIVE_EOF) goto out_done;
TST( ret != ARCHIVE_OK, errno = EINVAL,
"unable to read next archive header", out_error);
len = archive_read_data(archive_, buf_, sizeof(buf_));
TST( len == 0, errno = EINVAL, "zero-length tarball entry", out_skip);
TST( len < 0, errno = EINVAL, "negative-length tarball entry", out_error);
TST( len >= (ssize_t)sizeof(buf_), errno = EINVAL,
"tarball read overflow", out_error);
buf_[len] = 0;
bufp = StringPiece (buf_, len);
CHK(sc_tb.Init(this, NULL, bufp) != 0,
"unable to init tarball scannable", out_error);
CHK(scanner_->scan(&sc_tb) != 0,
"unable to scan tarball entry", out_error);
CHK(sc_tb.Destroy() != 0,
"unable to destroy tarball scannable", out_error);
out_skip:
*done = false;
return 0;
out_done:
*done = true;
return 0;
out_error:
*done = true;
if (ret != ARCHIVE_EOF)
printf("E %s %d %d %s\n",
archive_name_.as_string().c_str(),
ret,
archive_errno(archive_),
archive_error_string(archive_));
return 1;
}
int TarballTraversal::dbg_print_current_path(const char* msg, const char* frag) const
{
fprintf(stderr, "E %s path %s\n", msg, frag);
return 0;
}
int TarballTraversal::get_quoted_path(void*, string* qpath) const
{
*qpath = string(archive_entry_pathname(entry_));
return 0;
}