| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/zip.h" | 5 #include "chrome/common/zip.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 #endif | 166 #endif |
| 167 | 167 |
| 168 #if defined(OS_POSIX) | 168 #if defined(OS_POSIX) |
| 169 std::string src_file_str = src_file.value(); | 169 std::string src_file_str = src_file.value(); |
| 170 unzFile zip_file = unzOpen(src_file_str.c_str()); | 170 unzFile zip_file = unzOpen(src_file_str.c_str()); |
| 171 #elif defined(OS_WIN) | 171 #elif defined(OS_WIN) |
| 172 std::string src_file_str = WideToUTF8(src_file.value()); | 172 std::string src_file_str = WideToUTF8(src_file.value()); |
| 173 unzFile zip_file = unzOpen2(src_file_str.c_str(), &zip_funcs); | 173 unzFile zip_file = unzOpen2(src_file_str.c_str(), &zip_funcs); |
| 174 #endif | 174 #endif |
| 175 if (!zip_file) { | 175 if (!zip_file) { |
| 176 LOG(WARNING) << "couldn't create file " << src_file_str; | 176 DLOG(WARNING) << "couldn't create file " << src_file_str; |
| 177 return false; | 177 return false; |
| 178 } | 178 } |
| 179 unz_global_info zip_info; | 179 unz_global_info zip_info; |
| 180 int err; | 180 int err; |
| 181 err = unzGetGlobalInfo(zip_file, &zip_info); | 181 err = unzGetGlobalInfo(zip_file, &zip_info); |
| 182 if (err != UNZ_OK) { | 182 if (err != UNZ_OK) { |
| 183 LOG(WARNING) << "couldn't open zip " << src_file_str; | 183 DLOG(WARNING) << "couldn't open zip " << src_file_str; |
| 184 return false; | 184 return false; |
| 185 } | 185 } |
| 186 bool ret = true; | 186 bool ret = true; |
| 187 for (unsigned int i = 0; i < zip_info.number_entry; ++i) { | 187 for (unsigned int i = 0; i < zip_info.number_entry; ++i) { |
| 188 if (!ExtractCurrentFile(zip_file, dest_dir)) { | 188 if (!ExtractCurrentFile(zip_file, dest_dir)) { |
| 189 ret = false; | 189 ret = false; |
| 190 break; | 190 break; |
| 191 } | 191 } |
| 192 | 192 |
| 193 if (i + 1 < zip_info.number_entry) { | 193 if (i + 1 < zip_info.number_entry) { |
| 194 err = unzGoToNextFile(zip_file); | 194 err = unzGoToNextFile(zip_file); |
| 195 if (err != UNZ_OK) { | 195 if (err != UNZ_OK) { |
| 196 LOG(WARNING) << "error %d in unzGoToNextFile"; | 196 DLOG(WARNING) << "error %d in unzGoToNextFile"; |
| 197 ret = false; | 197 ret = false; |
| 198 break; | 198 break; |
| 199 } | 199 } |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 unzClose(zip_file); | 202 unzClose(zip_file); |
| 203 return ret; | 203 return ret; |
| 204 } | 204 } |
| 205 | 205 |
| 206 static bool AddFileToZip(zipFile zip_file, const FilePath& src_dir) { | 206 static bool AddFileToZip(zipFile zip_file, const FilePath& src_dir) { |
| 207 net::FileStream stream; | 207 net::FileStream stream; |
| 208 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; | 208 int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; |
| 209 if (stream.Open(src_dir, flags) != 0) { | 209 if (stream.Open(src_dir, flags) != 0) { |
| 210 LOG(ERROR) << "Could not open stream for path " | 210 DLOG(ERROR) << "Could not open stream for path " |
| 211 << src_dir.value(); | 211 << src_dir.value(); |
| 212 return false; | 212 return false; |
| 213 } | 213 } |
| 214 | 214 |
| 215 int num_bytes; | 215 int num_bytes; |
| 216 char buf[kZipBufSize]; | 216 char buf[kZipBufSize]; |
| 217 do { | 217 do { |
| 218 num_bytes = stream.Read(buf, kZipBufSize, net::CompletionCallback()); | 218 num_bytes = stream.Read(buf, kZipBufSize, net::CompletionCallback()); |
| 219 if (num_bytes > 0) { | 219 if (num_bytes > 0) { |
| 220 if (ZIP_OK != zipWriteInFileInZip(zip_file, buf, num_bytes)) { | 220 if (ZIP_OK != zipWriteInFileInZip(zip_file, buf, num_bytes)) { |
| 221 LOG(ERROR) << "Could not write data to zip for path " | 221 DLOG(ERROR) << "Could not write data to zip for path " |
| 222 << src_dir.value(); | 222 << src_dir.value(); |
| 223 return false; | 223 return false; |
| 224 } | 224 } |
| 225 } | 225 } |
| 226 } while (num_bytes > 0); | 226 } while (num_bytes > 0); |
| 227 | 227 |
| 228 return true; | 228 return true; |
| 229 } | 229 } |
| 230 | 230 |
| 231 static bool AddEntryToZip(zipFile zip_file, const FilePath& path, | 231 static bool AddEntryToZip(zipFile zip_file, const FilePath& path, |
| 232 const FilePath& root_path) { | 232 const FilePath& root_path) { |
| 233 #if defined(OS_WIN) | 233 #if defined(OS_WIN) |
| 234 std::string str_path = | 234 std::string str_path = |
| 235 WideToUTF8(path.value().substr(root_path.value().length() + 1)); | 235 WideToUTF8(path.value().substr(root_path.value().length() + 1)); |
| 236 ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/"); | 236 ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/"); |
| 237 #else | 237 #else |
| 238 std::string str_path = path.value().substr(root_path.value().length() + 1); | 238 std::string str_path = path.value().substr(root_path.value().length() + 1); |
| 239 #endif | 239 #endif |
| 240 | 240 |
| 241 bool is_directory = file_util::DirectoryExists(path); | 241 bool is_directory = file_util::DirectoryExists(path); |
| 242 if (is_directory) | 242 if (is_directory) |
| 243 str_path += "/"; | 243 str_path += "/"; |
| 244 | 244 |
| 245 if (ZIP_OK != zipOpenNewFileInZip( | 245 if (ZIP_OK != zipOpenNewFileInZip( |
| 246 zip_file, str_path.c_str(), | 246 zip_file, str_path.c_str(), |
| 247 NULL, NULL, 0u, NULL, 0u, NULL, // file info, extrafield local, length, | 247 NULL, NULL, 0u, NULL, 0u, NULL, // file info, extrafield local, length, |
| 248 // extrafield global, length, comment | 248 // extrafield global, length, comment |
| 249 Z_DEFLATED, Z_DEFAULT_COMPRESSION)) { | 249 Z_DEFLATED, Z_DEFAULT_COMPRESSION)) { |
| 250 LOG(ERROR) << "Could not open zip file entry " << str_path; | 250 DLOG(ERROR) << "Could not open zip file entry " << str_path; |
| 251 return false; | 251 return false; |
| 252 } | 252 } |
| 253 | 253 |
| 254 bool success = true; | 254 bool success = true; |
| 255 if (!is_directory) { | 255 if (!is_directory) { |
| 256 success = AddFileToZip(zip_file, path); | 256 success = AddFileToZip(zip_file, path); |
| 257 } | 257 } |
| 258 | 258 |
| 259 if (ZIP_OK != zipCloseFileInZip(zip_file)) { | 259 if (ZIP_OK != zipCloseFileInZip(zip_file)) { |
| 260 LOG(ERROR) << "Could not close zip file entry " << str_path; | 260 DLOG(ERROR) << "Could not close zip file entry " << str_path; |
| 261 return false; | 261 return false; |
| 262 } | 262 } |
| 263 | 263 |
| 264 return success; | 264 return success; |
| 265 } | 265 } |
| 266 | 266 |
| 267 bool Zip(const FilePath& src_dir, const FilePath& dest_file, | 267 bool Zip(const FilePath& src_dir, const FilePath& dest_file, |
| 268 const base::Callback<bool(const FilePath&)>& filter_cb) { | 268 const base::Callback<bool(const FilePath&)>& filter_cb) { |
| 269 DCHECK(file_util::DirectoryExists(src_dir)); | 269 DCHECK(file_util::DirectoryExists(src_dir)); |
| 270 | 270 |
| 271 #if defined(OS_WIN) | 271 #if defined(OS_WIN) |
| 272 zlib_filefunc_def zip_funcs; | 272 zlib_filefunc_def zip_funcs; |
| 273 fill_win32_filefunc(&zip_funcs); | 273 fill_win32_filefunc(&zip_funcs); |
| 274 zip_funcs.zopen_file = ZipOpenFunc; | 274 zip_funcs.zopen_file = ZipOpenFunc; |
| 275 #endif | 275 #endif |
| 276 | 276 |
| 277 #if defined(OS_POSIX) | 277 #if defined(OS_POSIX) |
| 278 std::string dest_file_str = dest_file.value(); | 278 std::string dest_file_str = dest_file.value(); |
| 279 std::string src_dir_str = src_dir.value(); | 279 std::string src_dir_str = src_dir.value(); |
| 280 zipFile zip_file = zipOpen(dest_file_str.c_str(), APPEND_STATUS_CREATE); | 280 zipFile zip_file = zipOpen(dest_file_str.c_str(), APPEND_STATUS_CREATE); |
| 281 #elif defined(OS_WIN) | 281 #elif defined(OS_WIN) |
| 282 std::string dest_file_str = WideToUTF8(dest_file.value()); | 282 std::string dest_file_str = WideToUTF8(dest_file.value()); |
| 283 zipFile zip_file = zipOpen2(dest_file_str.c_str(), APPEND_STATUS_CREATE, | 283 zipFile zip_file = zipOpen2(dest_file_str.c_str(), APPEND_STATUS_CREATE, |
| 284 NULL, // global comment | 284 NULL, // global comment |
| 285 &zip_funcs); | 285 &zip_funcs); |
| 286 #endif | 286 #endif |
| 287 | 287 |
| 288 if (!zip_file) { | 288 if (!zip_file) { |
| 289 LOG(WARNING) << "couldn't create file " << dest_file_str; | 289 DLOG(WARNING) << "couldn't create file " << dest_file_str; |
| 290 return false; | 290 return false; |
| 291 } | 291 } |
| 292 | 292 |
| 293 bool success = true; | 293 bool success = true; |
| 294 file_util::FileEnumerator file_enumerator( | 294 file_util::FileEnumerator file_enumerator( |
| 295 src_dir, true, // recursive | 295 src_dir, true, // recursive |
| 296 static_cast<file_util::FileEnumerator::FileType>( | 296 static_cast<file_util::FileEnumerator::FileType>( |
| 297 file_util::FileEnumerator::FILES | | 297 file_util::FileEnumerator::FILES | |
| 298 file_util::FileEnumerator::DIRECTORIES)); | 298 file_util::FileEnumerator::DIRECTORIES)); |
| 299 for (FilePath path = file_enumerator.Next(); !path.value().empty(); | 299 for (FilePath path = file_enumerator.Next(); !path.value().empty(); |
| 300 path = file_enumerator.Next()) { | 300 path = file_enumerator.Next()) { |
| 301 if (!filter_cb.Run(path)) { | 301 if (!filter_cb.Run(path)) { |
| 302 continue; | 302 continue; |
| 303 } | 303 } |
| 304 | 304 |
| 305 if (!AddEntryToZip(zip_file, path, src_dir)) { | 305 if (!AddEntryToZip(zip_file, path, src_dir)) { |
| 306 success = false; | 306 success = false; |
| 307 return false; | 307 return false; |
| 308 } | 308 } |
| 309 } | 309 } |
| 310 | 310 |
| 311 if (ZIP_OK != zipClose(zip_file, NULL)) { // global comment | 311 if (ZIP_OK != zipClose(zip_file, NULL)) { // global comment |
| 312 LOG(ERROR) << "Error closing zip file " << dest_file_str; | 312 DLOG(ERROR) << "Error closing zip file " << dest_file_str; |
| 313 return false; | 313 return false; |
| 314 } | 314 } |
| 315 | 315 |
| 316 return success; | 316 return success; |
| 317 } | 317 } |
| 318 | 318 |
| 319 static bool ExcludeNoFilesFilter(const FilePath& file_path) { | 319 static bool ExcludeNoFilesFilter(const FilePath& file_path) { |
| 320 return true; | 320 return true; |
| 321 } | 321 } |
| 322 | 322 |
| 323 static bool ExcludeHiddenFilesFilter(const FilePath& file_path) { | 323 static bool ExcludeHiddenFilesFilter(const FilePath& file_path) { |
| 324 return file_path.BaseName().value()[0] != '.'; | 324 return file_path.BaseName().value()[0] != '.'; |
| 325 } | 325 } |
| 326 | 326 |
| 327 bool Zip(const FilePath& src_dir, const FilePath& dest_file, | 327 bool Zip(const FilePath& src_dir, const FilePath& dest_file, |
| 328 bool include_hidden_files) { | 328 bool include_hidden_files) { |
| 329 if (include_hidden_files) { | 329 if (include_hidden_files) { |
| 330 return Zip(src_dir, dest_file, base::Bind(&ExcludeNoFilesFilter)); | 330 return Zip(src_dir, dest_file, base::Bind(&ExcludeNoFilesFilter)); |
| 331 } else { | 331 } else { |
| 332 return Zip(src_dir, dest_file, base::Bind(&ExcludeHiddenFilesFilter)); | 332 return Zip(src_dir, dest_file, base::Bind(&ExcludeHiddenFilesFilter)); |
| 333 } | 333 } |
| 334 } | 334 } |
| OLD | NEW |