0f82ec8e90990bfca4bdeca6faacd2019fedd70a
[platform/core/appfw/app-installers.git] / src / common / step / filesystem / step_unzip.cc
1 /* 2014, Copyright © Intel Coporation, APACHE-2.0, see LICENSE file */
2 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a apache 2.0 license that can be
4 // found in the LICENSE file.
5
6 #include "common/step/filesystem/step_unzip.h"
7
8 #include <tzplatform_config.h>
9
10 #include <boost/filesystem.hpp>
11 #include <boost/chrono/detail/system.hpp>
12 #include <cassert>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstdint>
16 #include <climits>
17 #include <cstring>
18 #include <string>
19
20 #include "common/utils/file_util.h"
21
22 namespace bf = boost::filesystem;
23 namespace bs = boost::system;
24
25 namespace {
26
27 const char kPackageUnpackDirPath[] = UNPACKDIR;
28
29 }  // namespace
30
31 namespace common_installer {
32 namespace filesystem {
33
34 Step::Status StepUnzip::precheck() {
35   if (context_->file_path.get().empty()) {
36     LOG(ERROR) << "file_path attribute is empty";
37     return Step::Status::INVALID_VALUE;
38   }
39   if (!boost::filesystem::exists(context_->file_path.get())) {
40     LOG(ERROR) << "file_path ("
41                << context_->file_path.get()
42                << ") path does not exist";
43     return Step::Status::INVALID_VALUE;
44   }
45
46   if (context_->root_application_path.get().empty()) {
47     LOG(ERROR) << "root_application_path attribute is empty";
48     return Step::Status::INVALID_VALUE;
49   }
50   if (!boost::filesystem::exists(context_->root_application_path.get())) {
51     LOG(ERROR) << "root_application_path ("
52                << context_->root_application_path.get()
53                << ") path does not exist";
54     return Step::Status::INVALID_VALUE;
55   }
56
57   return Step::Status::OK;
58 }
59
60 Step::Status StepUnzip::process() {
61   bf::path tmp_dir = GenerateTmpDir(kPackageUnpackDirPath);
62
63   int64_t required_size =
64       GetUnpackedPackageSize(context_->file_path.get());
65
66   if (required_size == -1) {
67     LOG(ERROR) << "Couldn't get uncompressed size for package: "
68                << context_->file_path.get();
69     return Step::Status::UNZIP_ERROR;
70   }
71
72   LOG(DEBUG) << "Required size for application: " << required_size << "B";
73
74   if (!CheckFreeSpaceAtPath(required_size, tmp_dir)) {
75     LOG(ERROR) << "There is not enough space to unpack application files";
76     return Step::Status::OUT_OF_SPACE;
77   }
78
79   if (!CheckFreeSpaceAtPath(required_size,
80       bf::path(context_->root_application_path.get()))) {
81     LOG(ERROR) << "There is not enough space to install application files";
82     return Step::Status::OUT_OF_SPACE;
83   }
84
85   // write unpacked directory for recovery file
86   if (context_->recovery_info.get().recovery_file) {
87     context_->recovery_info.get().recovery_file->set_unpacked_dir(tmp_dir);
88     context_->recovery_info.get().recovery_file->WriteAndCommitFileContent();
89   }
90
91   if (!CreateDir(tmp_dir)) {
92     LOG(ERROR) << "Failed to create temp directory: " << tmp_dir;
93     return Step::Status::APP_DIR_ERROR;
94   }
95
96
97   if (!ExtractToTmpDir(context_->file_path.get().string().c_str(), tmp_dir)) {
98     LOG(ERROR) << "Failed to process unpack step";
99     RemoveAll(tmp_dir);
100     return Step::Status::UNZIP_ERROR;
101   }
102   context_->unpacked_dir_path.set(tmp_dir);
103
104   LOG(INFO) << context_->file_path.get() << " was successfully unzipped into "
105       << context_->unpacked_dir_path.get();
106   return Status::OK;
107 }
108
109 Step::Status StepUnzip::undo() {
110   if (access(context_->unpacked_dir_path.get().string().c_str(), F_OK) == 0) {
111     RemoveAll(context_->unpacked_dir_path.get());
112     LOG(DEBUG) << "remove temp dir: " << context_->unpacked_dir_path.get();
113   }
114   return Status::OK;
115 }
116
117
118 }  // namespace filesystem
119 }  // namespace common_installer