Skip to content

Commit c22a883

Browse files
committed
Move archive functions to separate file.
1 parent 4e4b1d4 commit c22a883

10 files changed

Lines changed: 190 additions & 128 deletions

File tree

src/client/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include <access_table.h>
3535
#include <api.h>
36+
#include <archive.h>
3637
#include <config.h>
3738
#include <database.h>
3839
#include <filesystem.h>

src/common/archive.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2016, Egor Pugin
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* 3. Neither the name of the copyright holder nor the names of
13+
* its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
#include "archive.h"
29+
30+
#ifdef _WIN32
31+
#include <libarchive/archive.h>
32+
#include <libarchive/archive_entry.h>
33+
#else
34+
#include <archive.h>
35+
#include <archive_entry.h>
36+
#endif
37+
38+
#if !defined(_WIN32) && !defined(__APPLE__)
39+
#include <linux/limits.h>
40+
#endif
41+
42+
bool pack_files(const path &fn, const Files &files, const path &root_dir)
43+
{
44+
bool result = true;
45+
auto a = archive_write_new();
46+
archive_write_add_filter_gzip(a);
47+
archive_write_set_format_pax_restricted(a);
48+
archive_write_open_filename(a, fn.string().c_str());
49+
for (auto &f : files)
50+
{
51+
if (!fs::exists(f))
52+
{
53+
result = false;
54+
continue;
55+
}
56+
57+
// skip symlinks too
58+
if (!fs::is_regular_file(f))
59+
continue;
60+
61+
auto sz = fs::file_size(f);
62+
auto e = archive_entry_new();
63+
archive_entry_set_pathname(e, fs::relative(f, root_dir).string().c_str());
64+
archive_entry_set_size(e, sz);
65+
archive_entry_set_filetype(e, AE_IFREG);
66+
archive_entry_set_perm(e, 0644);
67+
archive_write_header(a, e);
68+
auto fp = fopen(f.string().c_str(), "rb");
69+
if (!fp)
70+
{
71+
archive_entry_free(e);
72+
result = false;
73+
continue;
74+
}
75+
char buff[8192];
76+
while (auto len = fread(buff, 1, sizeof(buff), fp))
77+
archive_write_data(a, buff, len);
78+
fclose(fp);
79+
archive_entry_free(e);
80+
}
81+
archive_write_close(a);
82+
archive_write_free(a);
83+
return result;
84+
}
85+
86+
Files unpack_file(const path &fn, const path &dst)
87+
{
88+
if (!fs::exists(dst))
89+
fs::create_directories(dst);
90+
91+
Files files;
92+
93+
auto a = archive_read_new();
94+
archive_read_support_filter_all(a);
95+
archive_read_support_format_all(a);
96+
auto r = archive_read_open_filename(a, fn.string().c_str(), 10240);
97+
if (r != ARCHIVE_OK)
98+
throw std::runtime_error(archive_error_string(a));
99+
archive_entry *entry;
100+
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
101+
{
102+
// act on regular files only
103+
auto type = archive_entry_filetype(entry);
104+
if (type != AE_IFREG)
105+
continue;
106+
107+
path f = dst / archive_entry_pathname(entry);
108+
path fdir = f.parent_path();
109+
if (!fs::exists(fdir))
110+
fs::create_directories(fdir);
111+
path filename = f.filename();
112+
if (filename == "." || filename == "..")
113+
continue;
114+
115+
auto fn = fs::absolute(f).string();
116+
// do not use fopen() because MSVC's file streams support UTF-16 characters
117+
// and we won't be able to unpack files under some tricky dir names
118+
std::ofstream o(fn, std::ios::out | std::ios::binary);
119+
if (!o)
120+
{
121+
// TODO: probably remove this and linux/limit.h header when server will be using hash paths
122+
#ifdef _WIN32
123+
if (fn.size() >= MAX_PATH)
124+
continue;
125+
#elif defined(__APPLE__)
126+
#else
127+
if (fn.size() >= PATH_MAX)
128+
continue;
129+
#endif
130+
throw std::runtime_error("Cannot open file: " + f.string());
131+
}
132+
while (1)
133+
{
134+
const void *buff;
135+
size_t size;
136+
int64_t offset;
137+
auto r = archive_read_data_block(a, &buff, &size, &offset);
138+
if (r == ARCHIVE_EOF)
139+
break;
140+
if (r < ARCHIVE_OK)
141+
throw std::runtime_error(archive_error_string(a));
142+
o.write((const char *)buff, size);
143+
}
144+
files.insert(f);
145+
}
146+
archive_read_close(a);
147+
archive_read_free(a);
148+
149+
return files;
150+
}

src/common/archive.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2016, Egor Pugin
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* 3. Neither the name of the copyright holder nor the names of
13+
* its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
#pragma once
29+
30+
#include "filesystem.h"
31+
32+
bool pack_files(const path &fn, const Files &files, const path &root_dir);
33+
Files unpack_file(const path &fn, const path &dst);

src/common/database.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "database.h"
2929

30+
#include "archive.h"
3031
#include "command.h"
3132
#include "date_time.h"
3233
#include "directories.h"

src/common/filesystem.cpp

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,11 @@
2727

2828
#include "filesystem.h"
2929

30-
#include "cppan_string.h"
31-
3230
#include <boost/algorithm/string.hpp>
3331

34-
#ifdef WIN32
35-
#include <libarchive/archive.h>
36-
#include <libarchive/archive_entry.h>
37-
#else
38-
#include <archive.h>
39-
#include <archive_entry.h>
40-
#endif
41-
4232
#include <iostream>
4333
#include <regex>
4434

45-
#if !defined(_WIN32) && !defined(__APPLE__)
46-
#include <linux/limits.h>
47-
#endif
48-
4935
String get_stamp_filename(const String &prefix)
5036
{
5137
return prefix + ".sha256";
@@ -212,116 +198,6 @@ bool is_under_root(path p, const path &root_dir)
212198
return false;
213199
}
214200

215-
bool pack_files(const path &fn, const Files &files, const path &root_dir)
216-
{
217-
bool result = true;
218-
auto a = archive_write_new();
219-
archive_write_add_filter_gzip(a);
220-
archive_write_set_format_pax_restricted(a);
221-
archive_write_open_filename(a, fn.string().c_str());
222-
for (auto &f : files)
223-
{
224-
if (!fs::exists(f))
225-
{
226-
result = false;
227-
continue;
228-
}
229-
230-
// skip symlinks too
231-
if (!fs::is_regular_file(f))
232-
continue;
233-
234-
auto sz = fs::file_size(f);
235-
auto e = archive_entry_new();
236-
archive_entry_set_pathname(e, fs::relative(f, root_dir).string().c_str());
237-
archive_entry_set_size(e, sz);
238-
archive_entry_set_filetype(e, AE_IFREG);
239-
archive_entry_set_perm(e, 0644);
240-
archive_write_header(a, e);
241-
auto fp = fopen(f.string().c_str(), "rb");
242-
if (!fp)
243-
{
244-
archive_entry_free(e);
245-
result = false;
246-
continue;
247-
}
248-
char buff[8192];
249-
while (auto len = fread(buff, 1, sizeof(buff), fp))
250-
archive_write_data(a, buff, len);
251-
fclose(fp);
252-
archive_entry_free(e);
253-
}
254-
archive_write_close(a);
255-
archive_write_free(a);
256-
return result;
257-
}
258-
259-
Files unpack_file(const path &fn, const path &dst)
260-
{
261-
if (!fs::exists(dst))
262-
fs::create_directories(dst);
263-
264-
Files files;
265-
266-
auto a = archive_read_new();
267-
archive_read_support_filter_all(a);
268-
archive_read_support_format_all(a);
269-
auto r = archive_read_open_filename(a, fn.string().c_str(), 10240);
270-
if (r != ARCHIVE_OK)
271-
throw std::runtime_error(archive_error_string(a));
272-
archive_entry *entry;
273-
while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
274-
{
275-
// act on regular files only
276-
auto type = archive_entry_filetype(entry);
277-
if (type != AE_IFREG)
278-
continue;
279-
280-
path f = dst / archive_entry_pathname(entry);
281-
path fdir = f.parent_path();
282-
if (!fs::exists(fdir))
283-
fs::create_directories(fdir);
284-
path filename = f.filename();
285-
if (filename == "." || filename == "..")
286-
continue;
287-
288-
auto fn = fs::absolute(f).string();
289-
// do not use fopen() because MSVC's file streams support UTF-16 characters
290-
// and we won't be able to unpack files under some tricky dir names
291-
std::ofstream o(fn, std::ios::out | std::ios::binary);
292-
if (!o)
293-
{
294-
// TODO: probably remove this and linux/limit.h header when server will be using hash paths
295-
#ifdef _WIN32
296-
if (fn.size() >= MAX_PATH)
297-
continue;
298-
#elif defined(__APPLE__)
299-
#else
300-
if (fn.size() >= PATH_MAX)
301-
continue;
302-
#endif
303-
throw std::runtime_error("Cannot open file: " + f.string());
304-
}
305-
while (1)
306-
{
307-
const void *buff;
308-
size_t size;
309-
int64_t offset;
310-
auto r = archive_read_data_block(a, &buff, &size, &offset);
311-
if (r == ARCHIVE_EOF)
312-
break;
313-
if (r < ARCHIVE_OK)
314-
throw std::runtime_error(archive_error_string(a));
315-
o.write((const char *)buff, size);
316-
}
317-
files.insert(f);
318-
}
319-
archive_read_close(a);
320-
archive_read_free(a);
321-
322-
return files;
323-
}
324-
325201
bool compare_files(const path &fn1, const path &fn2)
326202
{
327203
// open files at the end

src/common/filesystem.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ String make_archive_name(const String &fn = String());
7575
void copy_dir(const path &source, const path &destination);
7676
void remove_files_like(const path &dir, const String &regex);
7777

78-
bool pack_files(const path &fn, const Files &files, const path &root_dir);
79-
Files unpack_file(const path &fn, const path &dst);
80-
8178
bool compare_files(const path &fn1, const path &fn2);
8279
bool compare_dirs(const path &dir1, const path &dir2);
8380

@@ -87,7 +84,7 @@ namespace std
8784
{
8885
size_t operator()(const path& p) const
8986
{
90-
return boost::filesystem::hash_value(p);
87+
return fs::hash_value(p);
9188
}
9289
};
9390
}

src/common/project.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "project.h"
2929

30+
#include "archive.h"
3031
#include "bazel/bazel.h"
3132
#include "config.h"
3233
#include "command.h"

src/common/resolver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "resolver.h"
2929

3030
#include "access_table.h"
31+
#include "archive.h"
3132
#include "config.h"
3233
#include "database.h"
3334
#include "directories.h"

src/common/source.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "source.h"
2929

30+
#include "archive.h"
3031
#include "http.h"
3132
#include "templates.h"
3233

src/common/verifier.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "verifier.h"
2929

30+
#include "archive.h"
3031
#include "command.h"
3132
#include "config.h"
3233
#include "http.h"

0 commit comments

Comments
 (0)