Skip to content

Commit 5336e37

Browse files
miguelportillaseelabs
authored andcommitted
Add archive and lz4 extracting
1 parent c12dbc4 commit 5336e37

3 files changed

Lines changed: 161 additions & 0 deletions

File tree

src/ripple/basics/Archive.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2012, 2018 Ripple Labs Inc.
5+
6+
Permission to use, copy, modify, and/or distribute this software for any
7+
purpose with or without fee is hereby granted, provided that the above
8+
copyright notice and this permission notice appear in all copies.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
//==============================================================================
19+
20+
#ifndef RIPPLE_BASICS_ARCHIVE_H_INCLUDED
21+
#define RIPPLE_BASICS_ARCHIVE_H_INCLUDED
22+
23+
#include <boost/filesystem.hpp>
24+
25+
namespace ripple {
26+
27+
/** Extract a tar archive compressed with lz4
28+
29+
@param src the path of the archive to be extracted
30+
@param dst the directory to extract to
31+
32+
@throws runtime_error
33+
*/
34+
void
35+
extractTarLz4(
36+
boost::filesystem::path const& src,
37+
boost::filesystem::path const& dst);
38+
39+
} // ripple
40+
41+
#endif

src/ripple/basics/impl/Archive.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2012, 2018 Ripple Labs Inc.
5+
6+
Permission to use, copy, modify, and/or distribute this software for any
7+
purpose with or without fee is hereby granted, provided that the above
8+
copyright notice and this permission notice appear in all copies.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
//==============================================================================
19+
20+
#include <ripple/basics/Archive.h>
21+
#include <ripple/basics/contract.h>
22+
23+
#include <archive.h>
24+
#include <archive_entry.h>
25+
26+
namespace ripple {
27+
28+
void
29+
extractTarLz4(
30+
boost::filesystem::path const& src,
31+
boost::filesystem::path const& dst)
32+
{
33+
if (!is_regular_file(src))
34+
Throw<std::runtime_error>("Invalid source file");
35+
36+
using archive_ptr =
37+
std::unique_ptr<struct archive, void(*)(struct archive*)>;
38+
archive_ptr ar {archive_read_new(),
39+
[](struct archive* ar)
40+
{
41+
archive_read_free(ar);
42+
}};
43+
if (!ar)
44+
Throw<std::runtime_error>("Failed to allocate archive");
45+
46+
if (archive_read_support_format_tar(ar.get()) < ARCHIVE_OK)
47+
Throw<std::runtime_error>(archive_error_string(ar.get()));
48+
49+
if (archive_read_support_filter_lz4(ar.get()) < ARCHIVE_OK)
50+
Throw<std::runtime_error>(archive_error_string(ar.get()));
51+
52+
// Examples suggest this block size
53+
if (archive_read_open_filename(
54+
ar.get(), src.string().c_str(), 10240) < ARCHIVE_OK)
55+
{
56+
Throw<std::runtime_error>(archive_error_string(ar.get()));
57+
}
58+
59+
archive_ptr aw {archive_write_disk_new(),
60+
[](struct archive* aw)
61+
{
62+
archive_write_free(aw);
63+
}};
64+
if (!aw)
65+
Throw<std::runtime_error>("Failed to allocate archive");
66+
67+
if (archive_write_disk_set_options(
68+
aw.get(),
69+
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM |
70+
ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS) < ARCHIVE_OK)
71+
{
72+
Throw<std::runtime_error>(archive_error_string(aw.get()));
73+
}
74+
75+
if(archive_write_disk_set_standard_lookup(aw.get()) < ARCHIVE_OK)
76+
Throw<std::runtime_error>(archive_error_string(aw.get()));
77+
78+
int result;
79+
struct archive_entry* entry;
80+
while(true)
81+
{
82+
result = archive_read_next_header(ar.get(), &entry);
83+
if (result == ARCHIVE_EOF)
84+
break;
85+
if (result < ARCHIVE_OK)
86+
Throw<std::runtime_error>(archive_error_string(ar.get()));
87+
88+
archive_entry_set_pathname(
89+
entry, (dst / archive_entry_pathname(entry)).string().c_str());
90+
if (archive_write_header(aw.get(), entry) < ARCHIVE_OK)
91+
Throw<std::runtime_error>(archive_error_string(aw.get()));
92+
93+
if (archive_entry_size(entry) > 0)
94+
{
95+
const void *buf;
96+
size_t sz;
97+
la_int64_t offset;
98+
while (true)
99+
{
100+
result = archive_read_data_block(ar.get(), &buf, &sz, &offset);
101+
if (result == ARCHIVE_EOF)
102+
break;
103+
if (result < ARCHIVE_OK)
104+
Throw<std::runtime_error>(archive_error_string(ar.get()));
105+
106+
if (archive_write_data_block(
107+
aw.get(), buf, sz, offset) < ARCHIVE_OK)
108+
{
109+
Throw<std::runtime_error>(archive_error_string(aw.get()));
110+
}
111+
}
112+
}
113+
114+
if (archive_write_finish_entry(aw.get()) < ARCHIVE_OK)
115+
Throw<std::runtime_error>(archive_error_string(aw.get()));
116+
}
117+
}
118+
119+
} // ripple

src/ripple/unity/basics2.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
#include <ripple/basics/impl/ResolverAsio.cpp>
2525
#include <ripple/basics/impl/Sustain.cpp>
2626
#include <ripple/basics/impl/UptimeClock.cpp>
27+
#include <ripple/basics/impl/Archive.cpp>
2728

2829

0 commit comments

Comments
 (0)