blob: d844e7ecd077d47a9fce962d24ce5181a5b2264b [file] [log] [blame]
Darin Petkov083047b2011-06-23 20:42:48 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/key_file_store.h"
6
7#include <base/file_util.h>
8#include <base/logging.h>
9
10using std::set;
11using std::string;
12
13namespace shill {
14
15KeyFileStore::KeyFileStore(GLib *glib) : glib_(glib), key_file_(NULL) {}
16
17KeyFileStore::~KeyFileStore() {
18 ReleaseKeyFile();
19}
20
21void KeyFileStore::ReleaseKeyFile() {
22 if (key_file_) {
23 glib_->KeyFileFree(key_file_);
24 key_file_ = NULL;
25 }
26}
27
28bool KeyFileStore::Open() {
29 CHECK(!path_.empty());
30 CHECK(!key_file_);
31 key_file_ = glib_->KeyFileNew();
32 int64 file_size = 0;
33 if (!file_util::GetFileSize(path_, &file_size) || file_size == 0) {
34 LOG(INFO) << "Creating a new key file at " << path_.value();
35 return true;
36 }
37 GError *error = NULL;
38 if (glib_->KeyFileLoadFromFile(
39 key_file_,
40 path_.value().c_str(),
41 static_cast<GKeyFileFlags>(G_KEY_FILE_KEEP_COMMENTS |
42 G_KEY_FILE_KEEP_TRANSLATIONS),
43 &error)) {
44 return true;
45 }
46 LOG(ERROR) << "Failed to load key file from " << path_.value() << ": "
47 << glib_->ConvertErrorToMessage(error);
48 ReleaseKeyFile();
49 return false;
50}
51
52bool KeyFileStore::Close() {
53 CHECK(key_file_);
54 GError *error = NULL;
55 gsize length = 0;
56 gchar *data = glib_->KeyFileToData(key_file_, &length, &error);
57 ReleaseKeyFile();
58
59 bool success = true;
60 if (path_.empty()) {
61 LOG(ERROR) << "Empty key file path.";
62 success = false;
63 }
64 if (success && (!data || error)) {
65 LOG(ERROR) << "Failed to convert key file to string: "
66 << glib_->ConvertErrorToMessage(error);
67 success = false;
68 }
69 if (success && file_util::WriteFile(path_, data, length) != length) {
70 LOG(ERROR) << "Failed to store key file: " << path_.value();
71 success = false;
72 }
73 glib_->Free(data);
74 return success;
75}
76
77set<string> KeyFileStore::GetGroups() {
78 CHECK(key_file_);
79 gsize length = 0;
80 gchar **groups = g_key_file_get_groups(key_file_, &length);
81 if (!groups) {
82 LOG(ERROR) << "Unable to obtain groups.";
83 return set<string>();
84 }
85 set<string> group_set(groups, groups + length);
86 glib_->Strfreev(groups);
87 return group_set;
88}
89
90bool KeyFileStore::ContainsGroup(const string &group) {
91 CHECK(key_file_);
92 return glib_->KeyFileHasGroup(key_file_, group.c_str());
93}
94
95bool KeyFileStore::DeleteKey(const string &group, const string &key) {
96 CHECK(key_file_);
97 GError *error = NULL;
98 glib_->KeyFileRemoveKey(key_file_, group.c_str(), key.c_str(), &error);
99 if (error) {
100 LOG(ERROR) << "Failed to delete (" << group << ":" << key << "): "
101 << glib_->ConvertErrorToMessage(error);
102 return false;
103 }
104 return true;
105}
106
107bool KeyFileStore::DeleteGroup(const string &group) {
108 CHECK(key_file_);
109 GError *error = NULL;
110 glib_->KeyFileRemoveGroup(key_file_, group.c_str(), &error);
111 if (error) {
112 LOG(ERROR) << "Failed to delete group " << group << "): "
113 << glib_->ConvertErrorToMessage(error);
114 return false;
115 }
116 return true;
117}
118
119bool KeyFileStore::GetString(const string &group,
120 const string &key,
121 string *value) {
122 CHECK(key_file_);
123 GError *error = NULL;
124 gchar *data =
125 glib_->KeyFileGetString(key_file_, group.c_str(), key.c_str(), &error);
126 if (!data) {
127 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
128 << glib_->ConvertErrorToMessage(error);
129 return false;
130 }
131 if (value) {
132 *value = data;
133 }
134 glib_->Free(data);
135 return true;
136}
137
138bool KeyFileStore::SetString(const string &group,
139 const string &key,
140 const string &value) {
141 CHECK(key_file_);
142 glib_->KeyFileSetString(key_file_, group.c_str(), key.c_str(), value.c_str());
143 return true;
144}
145
146bool KeyFileStore::GetBool(const string &group,
147 const string &key,
148 bool *value) {
149 CHECK(key_file_);
150 GError *error = NULL;
151 gboolean data =
152 glib_->KeyFileGetBoolean(key_file_, group.c_str(), key.c_str(), &error);
153 if (error) {
154 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
155 << glib_->ConvertErrorToMessage(error);
156 return false;
157 }
158 if (value) {
159 *value = data;
160 }
161 return true;
162}
163
164bool KeyFileStore::SetBool(const string &group, const string &key, bool value) {
165 CHECK(key_file_);
166 glib_->KeyFileSetBoolean(key_file_,
167 group.c_str(),
168 key.c_str(),
169 value ? TRUE : FALSE);
170 return true;
171}
172
173bool KeyFileStore::GetInt(const string &group, const string &key, int *value) {
174 CHECK(key_file_);
175 GError *error = NULL;
176 gint data =
177 glib_->KeyFileGetInteger(key_file_, group.c_str(), key.c_str(), &error);
178 if (error) {
179 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
180 << glib_->ConvertErrorToMessage(error);
181 return false;
182 }
183 if (value) {
184 *value = data;
185 }
186 return true;
187}
188
189bool KeyFileStore::SetInt(const string &group, const string &key, int value) {
190 CHECK(key_file_);
191 glib_->KeyFileSetInteger(key_file_, group.c_str(), key.c_str(), value);
192 return true;
193}
194
195} // namespace shill