• R/O
  • SSH
  • HTTPS

hamigaki: 提交


Commit MetaInfo

修訂1612 (tree)
時間2008-04-25 22:48:23
作者hamigaki

Log Message

added wtar.cpp

Change Summary

差異

--- hamigaki/trunk/libs/archivers/example/wtar.cpp (nonexistent)
+++ hamigaki/trunk/libs/archivers/example/wtar.cpp (revision 1612)
@@ -0,0 +1,181 @@
1+// wtar.cpp: a simple tar archiver (Unicode version)
2+
3+// Copyright Takeshi Mouri 2008.
4+// Distributed under the Boost Software License, Version 1.0.
5+// (See accompanying file LICENSE_1_0.txt or copy at
6+// http://www.boost.org/LICENSE_1_0.txt)
7+
8+// See http://hamigaki.sourceforge.jp/libs/archivers for library home page.
9+
10+#include <boost/config.hpp>
11+
12+#include <hamigaki/archivers/tar_file.hpp>
13+#include <hamigaki/filesystem/operations.hpp>
14+#include <hamigaki/iostreams/device/file_descriptor.hpp>
15+#include <boost/filesystem/fstream.hpp>
16+#include <boost/iostreams/copy.hpp>
17+#include <clocale>
18+#include <exception>
19+#include <iostream>
20+#include <vector>
21+
22+#if defined(BOOST_WINDOWS)
23+#elif defined(BOOST_HAS_UNISTD_H)
24+ #include <grp.h>
25+ #include <pwd.h>
26+ #include <unistd.h>
27+#endif
28+
29+#if defined(BOOST_WINDOWS)
30+ #include <windows.h>
31+ #if !defined(__GNUC__)
32+ #pragma comment(lib, "shell32.lib")
33+ #endif
34+#else
35+ #include <cstdlib>
36+#endif
37+
38+namespace ar = hamigaki::archivers;
39+namespace fs_ex = hamigaki::filesystem;
40+namespace io_ex = hamigaki::iostreams;
41+namespace fs = boost::filesystem;
42+namespace io = boost::iostreams;
43+
44+#if defined(BOOST_WINDOWS)
45+class scoped_local_memory : private boost::noncopyable
46+{
47+public:
48+ explicit scoped_local_memory(void* p) : ptr_(p)
49+ {
50+ }
51+
52+ ~scoped_local_memory()
53+ {
54+ if (ptr_)
55+ ::LocalFree(ptr_);
56+ }
57+
58+private:
59+ void* ptr_;
60+};
61+
62+void get_cmd_line_args(int, char**, std::vector<std::wstring>& args)
63+{
64+ int argc = 0;
65+ wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
66+ scoped_local_memory guard(argv);
67+ args.assign(argv, argv+argc);
68+}
69+#else
70+std::wstring narrow_to_wide(const char* s)
71+{
72+ std::size_t size = std::mbstowcs(0, s, 0);
73+ if (size == static_cast<std::size_t>(-1))
74+ throw std::runtime_error("failed mbstowcs()");
75+
76+ boost::scoped_array<wchar_t> buf(new wchar_t[size+1]);
77+ size = std::mbstowcs(buf.get(), s, size+1);
78+ if (size == static_cast<std::size_t>(-1))
79+ throw std::runtime_error("failed mbstowcs()");
80+
81+ return std::wstring(buf.get(), size);
82+}
83+
84+void get_cmd_line_args(int argc, char** argv, std::vector<std::wstring>& args)
85+{
86+ std::vector<std::wstring> tmp;
87+ tmp.reserve(count);
88+ std::transform(argv, argv+argc, std::back_inserter(tmp), &narrow_to_wide);
89+ args.swap(tmp);
90+}
91+#endif
92+
93+int main(int argc, char* argv[])
94+{
95+ try
96+ {
97+ if (argc < 3)
98+ {
99+ std::cerr << "Usage: wtar (archive) (filename) ..." << std::endl;
100+ return 1;
101+ }
102+
103+ std::setlocale(LC_ALL, "");
104+
105+ std::vector<std::wstring> args;
106+ get_cmd_line_args(argc, argv, args);
107+
108+ // file_descriptor_sink supports 64bit offset
109+ ar::basic_tar_file_sink<io_ex::file_descriptor_sink,fs::wpath>
110+ tar((io_ex::file_descriptor_sink(
111+ std::string(argv[1]), BOOST_IOS::binary)));
112+
113+ for (int i = 2; i < argc; ++i)
114+ {
115+ ar::tar::wheader head;
116+ head.format = ar::tar::pax;
117+ head.path = args[i];
118+
119+ const fs_ex::file_status& s = fs_ex::symlink_status(head.path);
120+
121+ if (is_symlink(s))
122+ {
123+ head.type_flag = ar::tar::type_flag::symlink;
124+ head.link_path = fs_ex::symlink_target(head.path);
125+ }
126+ else if (is_directory(s))
127+ head.type_flag = ar::tar::type_flag::directory;
128+ else
129+ head.file_size = s.file_size();
130+
131+ head.modified_time = s.last_write_time();
132+ head.access_time = s.last_access_time();
133+
134+ if (s.has_last_change_time())
135+ head.change_time = s.last_change_time();
136+
137+ if (s.has_permissions())
138+ head.permissions = s.permissions();
139+
140+ if (s.has_uid() && s.has_gid())
141+ {
142+ head.uid = s.uid();
143+ head.gid = s.gid();
144+ }
145+
146+#if defined(BOOST_WINDOWS)
147+ head.user_name = L"root";
148+ head.group_name = L"root";
149+#elif defined(BOOST_HAS_UNISTD_H)
150+ if (s.has_uid())
151+ {
152+ if (passwd* p = ::getpwuid(s.uid()))
153+ head.user_name = p->pw_name;
154+ }
155+ if (s.has_gid())
156+ {
157+ if (group* p = ::getgrgid(s.gid()))
158+ head.group_name = p->gr_name;
159+ }
160+#endif
161+
162+ tar.create_entry(head);
163+
164+ if (!fs::is_directory(head.path))
165+ {
166+ fs::ifstream is(head.path, std::ios_base::binary);
167+ if (!is)
168+ throw std::runtime_error("cannot open file");
169+
170+ io::copy(is, tar);
171+ }
172+ }
173+ tar.close_archive();
174+ return 0;
175+ }
176+ catch (const std::exception& e)
177+ {
178+ std::cerr << "Error: " << e.what() << std::endl;
179+ }
180+ return 1;
181+}
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Show on old repository browser