Remove unnecessary function
[platform/core/appfw/app-installers.git] / src / common / recovery_file.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/recovery_file.h"
6
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/system/error_code.hpp>
9
10 #include <manifest_parser/utils/logging.h>
11
12 #include <array>
13 #include <cstring>
14 #include <map>
15 #include <utility>
16
17 #include "common/installer_context.h"
18 #include "common/utils/file_util.h"
19
20 namespace bf = boost::filesystem;
21 namespace bs = boost::system;
22 namespace ci = common_installer;
23
24 namespace {
25
26 const char kRecoveryInstallString[] = "NEW";
27 const char kRecoveryUpdateString[] = "UPDATE";
28 const char kRecoveryUninstallationString[] = "UNINSTALL";
29 const char kRecoveryRdsString[] = "RDS";
30 const char kRecoveryDeltaString[] = "DELTA";
31 const char kRecoveryMountInstallString[] = "MOUNTINSTALL";
32 const char kRecoveryMountUpdateString[] = "MOUNTUPDATE";
33 const char kRecoveryReadonlyUpdateInstallString[] = "READONLYUPDATEINSTALL";
34 const char kRecoveryUnknownString[] = "UNKNOWN";
35
36 const std::map<std::string, ci::RequestType> kStringToRequestMap = {
37   {kRecoveryInstallString, ci::RequestType::Install},
38   {kRecoveryUpdateString, ci::RequestType::Update},
39   {kRecoveryUninstallationString, ci::RequestType::Uninstall},
40   {kRecoveryRdsString, ci::RequestType::Reinstall},
41   {kRecoveryDeltaString, ci::RequestType::Delta},
42   {kRecoveryMountInstallString, ci::RequestType::MountInstall},
43   {kRecoveryMountUpdateString, ci::RequestType::MountUpdate},
44   {kRecoveryReadonlyUpdateInstallString,
45       ci::RequestType::ReadonlyUpdateInstall},
46 };
47
48 std::string TruncateNewLine(const char* data) {
49   int length = strlen(data);
50   if (data[length - 1] == '\n')
51       --length;
52   return std::string(data, length);
53 }
54
55 }  // namespace
56
57 namespace common_installer {
58 namespace recovery {
59
60 std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFile(
61     const boost::filesystem::path& path, RequestType type) {
62   if (bf::exists(path)) {
63     LOG(ERROR) << "Recovery file already exists!";
64     return nullptr;
65   }
66   std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, type, false));
67   if (file->is_detached()) {
68     LOG(ERROR) << "Failed to access file";
69     return nullptr;
70   }
71   return file;
72 }
73
74 std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFile(
75     const boost::filesystem::path& path) {
76   if (!bf::exists(path)) {
77     LOG(ERROR) << "Cannot open recovery file";
78     return nullptr;
79   }
80   std::unique_ptr<RecoveryFile> file(new RecoveryFile(path,
81       RequestType::Unknown, true));
82   if (file->is_detached()) {
83     LOG(ERROR) << "Failed to read recovery file";
84     return nullptr;
85   }
86   return file;
87 }
88
89 RecoveryFile::RecoveryFile(const bf::path& path, RequestType type, bool load)
90     : type_(type), path_(path), backup_done_(false) {
91   if (load) {
92     if (!ReadFileContent()) {
93       path_.clear();
94       return;
95     }
96   } else {
97     // create file
98     if (!WriteAndCommitFileContent()) {
99       path_.clear();
100       return;
101     }
102     LOG(DEBUG) << "Recovery file " << path_ << " created";
103   }
104 }
105
106 RecoveryFile::~RecoveryFile() {
107   if (Remove(path_))
108     LOG(DEBUG) << "Recovery file " << path_ << " removed";
109 }
110
111 void RecoveryFile::Detach() {
112   path_.clear();
113 }
114
115 bool RecoveryFile::is_detached() const {
116   return path_.empty();
117 }
118
119 void RecoveryFile::set_unpacked_dir(
120     boost::filesystem::path unpacked_dir) {
121   unpacked_dir_ = std::move(unpacked_dir);
122 }
123
124 void RecoveryFile::set_pkgid(std::string pkgid) {
125   pkgid_ = std::move(pkgid);
126 }
127
128
129 void RecoveryFile::set_backup_done(bool backup_done) {
130   backup_done_ = backup_done;
131 }
132
133 const boost::filesystem::path& RecoveryFile::unpacked_dir() const {
134   return unpacked_dir_;
135 }
136
137 const std::string& RecoveryFile::pkgid() const {
138   return pkgid_;
139 }
140
141 RequestType RecoveryFile::type() const {
142   return type_;
143 }
144
145 bool RecoveryFile::backup_done() const {
146   return backup_done_;
147 }
148
149 bool RecoveryFile::ReadFileContent() {
150   FILE* handle = fopen(path_.c_str(), "r");
151   if (!handle) {
152     LOG(ERROR) << "Cannot read recovery file";
153     return false;
154   }
155   std::array<char, 200> data;
156   data[0] = '\0';
157   if (!fgets(data.data(), data.size(), handle)) {
158     type_ = RequestType::Unknown;
159     fclose(handle);
160     return true;
161   }
162   std::string mode(TruncateNewLine(data.data()));
163   auto iter = kStringToRequestMap.find(mode);
164   if (iter == kStringToRequestMap.end()) {
165     type_ = RequestType::Unknown;
166   } else {
167     type_ = iter->second;
168   }
169
170   if (!fgets(data.data(), data.size(), handle)) {
171     fclose(handle);
172     return true;
173   }
174   unpacked_dir_ = TruncateNewLine(data.data());
175   if (!fgets(data.data(), data.size(), handle)) {
176     fclose(handle);
177     return true;
178   }
179   pkgid_ = TruncateNewLine(data.data());
180   if (!fgets(data.data(), data.size(), handle)) {
181     fclose(handle);
182     return true;
183   }
184   std::string backup_flag = TruncateNewLine(data.data());
185   if (backup_flag == "true")
186     backup_done_ = true;
187   else
188     backup_done_ = false;
189   fclose(handle);
190   return true;
191 }
192
193 bool RecoveryFile::WriteAndCommitFileContent() {
194   Remove(path_);
195   FILE* handle = fopen(path_.c_str(), "wx");
196   if (!handle) {
197     LOG(ERROR) << "Cannot write recovery file";
198     return false;
199   }
200   switch (type_) {
201   case RequestType::Install:
202     fputs(kRecoveryInstallString, handle);
203     break;
204   case RequestType::Update:
205     fputs(kRecoveryUpdateString, handle);
206     break;
207   case RequestType::Uninstall:
208     fputs(kRecoveryUninstallationString, handle);
209     break;
210   case RequestType::Reinstall:
211     fputs(kRecoveryRdsString, handle);
212     break;
213   case RequestType::Delta:
214     fputs(kRecoveryDeltaString, handle);
215     break;
216   case RequestType::MountInstall:
217     fputs(kRecoveryMountInstallString, handle);
218     break;
219   case RequestType::MountUpdate:
220     fputs(kRecoveryMountUpdateString, handle);
221     break;
222   case RequestType::ReadonlyUpdateInstall:
223     fputs(kRecoveryReadonlyUpdateInstallString, handle);
224     break;
225   default:
226     fputs(kRecoveryUnknownString, handle);
227     break;
228   }
229   fputs("\n", handle);
230   fputs(unpacked_dir_.c_str(), handle);
231   fputs("\n", handle);
232   fputs(pkgid_.c_str(), handle);
233   fputs("\n", handle);
234   fputs(backup_done_ ? "true" : "false", handle);
235   fputs("\n", handle);
236   fclose(handle);
237   sync();
238   return true;
239 }
240
241 }  // namespace recovery
242 }  // namespace common_installer
243