Commit | Line | Data |
---|---|---|
6beab33f | 1 | /** @file |
e0080b78 | 2 | * @brief Serviceholder class implementation. This class holds Service and OldService lists. |
6beab33f BS |
3 | * |
4 | * | |
5 | * | |
6 | * @copyright Intra2net AG | |
7 | * @license GPLv2 | |
8 | */ | |
9 | ||
4de6a9b8 | 10 | #include "serviceholder.hpp" |
6beab33f | 11 | |
ca5d6889 | 12 | #include <fstream> |
e0080b78 | 13 | |
ca5d6889 | 14 | #include <boost/foreach.hpp> |
e0080b78 | 15 | #include <boost/filesystem.hpp> |
ca5d6889 | 16 | |
04e3d681 | 17 | #define OBJECT_FILE "/var/state/bpdyndnsd/bpdyndnsd.state" |
88a594e8 | 18 | |
6beab33f BS |
19 | using namespace std; |
20 | ||
ca5d6889 BS |
21 | namespace fs = boost::filesystem; |
22 | ||
6beab33f BS |
23 | |
24 | /** | |
31af6a2e BS |
25 | * Default constructor. |
26 | */ | |
27 | Serviceholder::Serviceholder() | |
28 | :Log(new Logger) | |
29 | ,IPAddrHelp() | |
30 | { | |
31 | } | |
32 | ||
33 | ||
34 | /** | |
35 | * Constructor with Logger object. | |
6beab33f | 36 | */ |
e0080b78 | 37 | Serviceholder::Serviceholder(Logger::Ptr _log) |
9a0aff44 | 38 | :Log(_log) |
20399847 | 39 | ,IPAddrHelp() |
6beab33f BS |
40 | { |
41 | } | |
42 | ||
43 | ||
44 | /** | |
45 | * Default destructor. While serializing and deserializing we use boost/shared_ptr, the resources are managed correctly. | |
46 | */ | |
47 | Serviceholder::~Serviceholder() | |
48 | { | |
49 | } | |
50 | ||
51 | ||
52 | /** | |
e0080b78 BS |
53 | * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file. |
54 | * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing. | |
6beab33f | 55 | */ |
c730deea | 56 | int Serviceholder::serialize_services() const |
6beab33f | 57 | { |
e0080b78 BS |
58 | // Put Services and OldServices into Serviceholder. |
59 | SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer); | |
60 | ||
c730deea | 61 | BOOST_FOREACH(const Service::Ptr &service, Services) |
e0080b78 BS |
62 | { |
63 | service_container->add_service(service); | |
64 | } | |
65 | ||
62df5f33 | 66 | time_t current_time = time(NULL); |
e0080b78 | 67 | |
c730deea | 68 | BOOST_FOREACH(const Service::Ptr &service, OldServices) |
e0080b78 | 69 | { |
623751fb | 70 | if ( !service->get_last_updates().empty() && |
4553e833 | 71 | ( service->get_last_update_time() + ((time_t)service->get_update_interval()*60) ) >= current_time ) /*lint !e1793 */ // UpdateInterval timeout of service isn't expired. |
e0080b78 BS |
72 | service_container->add_service(service); |
73 | } | |
74 | ||
20399847 | 75 | // Serialize SerializeServiceContainer and IPAddrHelper into file. |
e0080b78 BS |
76 | ofstream ofs(OBJECT_FILE); |
77 | if ( ofs.is_open() ) | |
78 | { | |
79 | SerializeServiceContainer* _service_container = service_container.get(); | |
20399847 | 80 | IPAddrHelper* _ip_addr_helper = IPAddrHelp.get(); |
e0080b78 BS |
81 | try |
82 | { | |
83 | boost::archive::text_oarchive oa(ofs); | |
20399847 | 84 | oa << _service_container << _ip_addr_helper; |
e0080b78 | 85 | } |
08a5a621 | 86 | catch( const boost::archive::archive_exception& e ) |
e0080b78 BS |
87 | { |
88 | Log->print_exception_serialize(e.what()); | |
89 | ofs.close(); | |
90 | return -1; | |
91 | } | |
92 | ||
93 | ofs.close(); | |
94 | } | |
95 | else | |
96 | { | |
97 | Log->print_error_opening_rw(OBJECT_FILE); | |
98 | return -1; | |
99 | } | |
100 | ||
101 | Log->print_serialized_objects_success(); | |
102 | ||
103 | return 0; | |
6beab33f BS |
104 | } |
105 | ||
106 | ||
107 | /** | |
e0080b78 BS |
108 | * This function de-serializes the SerializeServiceContainer (containing Services) from the object file. |
109 | * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing. | |
110 | */ | |
111 | int Serviceholder::deserialize_services() | |
112 | { | |
113 | // test if OBJECT_FILE exists | |
114 | fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE)); | |
115 | if ( !fs::exists(object_file) ) | |
116 | { | |
117 | // There is no object file, possibly first program start, continue without recovering old Services' state. | |
118 | Log->print_no_object_file(OBJECT_FILE); | |
119 | return 0; | |
120 | } | |
121 | ||
122 | ifstream ifs(OBJECT_FILE); | |
123 | if ( ifs.is_open() ) | |
124 | { | |
125 | // deserialize SerializeServiceContainer | |
126 | SerializeServiceContainer* _service_container; | |
20399847 | 127 | IPAddrHelper* _ip_addr_helper; |
e0080b78 BS |
128 | try |
129 | { | |
130 | boost::archive::text_iarchive ia(ifs); | |
20399847 | 131 | ia >> _service_container >> _ip_addr_helper; |
e0080b78 | 132 | } |
08a5a621 | 133 | catch( const boost::archive::archive_exception& e ) |
e0080b78 BS |
134 | { |
135 | Log->print_exception_deserialize(e.what()); | |
136 | ifs.close(); | |
137 | return -1; | |
138 | } | |
139 | SerializeServiceContainer::Ptr service_container(_service_container); | |
c3c84086 | 140 | IPAddrHelp = IPAddrHelper::Ptr(_ip_addr_helper); |
e0080b78 BS |
141 | ifs.close(); |
142 | ||
143 | // Get the list of old Services from de-serialized SerializeServiceContainer object. | |
144 | list<Service::Ptr> _old_services = service_container->get_containing_services(); | |
145 | ||
146 | // Put all de-serialized Services into OldServices member and | |
147 | // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file) | |
148 | // if identical Service was found, adopt the value from old Service to recover Services' state. | |
149 | BOOST_FOREACH(Service::Ptr &old_service, _old_services) | |
150 | { | |
151 | OldServices.push_back(old_service); | |
4553e833 | 152 | Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_max_equal_updates_in_succession(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates()); |
e0080b78 BS |
153 | BOOST_FOREACH(Service::Ptr &service, Services) |
154 | { | |
155 | if ( *service == *old_service ) | |
156 | { | |
157 | service->set_last_updates(old_service->get_last_updates()); | |
158 | service->set_actual_ip(old_service->get_actual_ip()); | |
4553e833 | 159 | Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_max_equal_updates_in_succession(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates()); |
e0080b78 BS |
160 | // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized. |
161 | old_service->set_update_interval(0); | |
162 | } | |
163 | } | |
164 | } | |
165 | Log->print_deserialized_objects_success(); | |
166 | } | |
167 | else | |
168 | { | |
169 | Log->print_error_opening_r(OBJECT_FILE); | |
170 | return -1; | |
171 | } | |
172 | ||
173 | return 0; | |
174 | } | |
175 | ||
176 | ||
177 | /** | |
178 | * Add service to internal service list. | |
179 | * @param service Shared pointer to service object. | |
6beab33f | 180 | */ |
88a594e8 | 181 | void Serviceholder::add_service(Service::Ptr service) |
6beab33f | 182 | { |
e0080b78 BS |
183 | Services.push_back(service); |
184 | } | |
185 | ||
186 | ||
187 | /** | |
188 | * Resets all shared Service pointers and clears the Services list. | |
189 | */ | |
190 | void Serviceholder::delete_services() | |
191 | { | |
192 | BOOST_FOREACH( Service::Ptr &service, Services ) | |
193 | { | |
194 | service.reset(); | |
195 | } | |
196 | Services.clear(); | |
197 | ||
198 | BOOST_FOREACH( Service::Ptr &service, OldServices ) | |
199 | { | |
200 | service.reset(); | |
201 | } | |
202 | OldServices.clear(); | |
20399847 BS |
203 | |
204 | IPAddrHelp.reset(); | |
6beab33f BS |
205 | } |
206 | ||
207 | ||
208 | /** | |
e0080b78 BS |
209 | * Getter for member Services |
210 | * @return List with shared Service pointers. | |
6beab33f | 211 | */ |
e0080b78 | 212 | std::list<Service::Ptr> Serviceholder::get_services() const |
6beab33f | 213 | { |
e0080b78 | 214 | return Services; |
6beab33f | 215 | } |
20399847 BS |
216 | |
217 | ||
218 | /** | |
219 | * Set member IPAddrHelp | |
220 | * @param _ip_addr_helper The IPAddrHelper. | |
221 | */ | |
222 | void Serviceholder::set_ip_addr_helper(IPAddrHelper::Ptr _ip_addr_helper) | |
223 | { | |
224 | IPAddrHelp = _ip_addr_helper; | |
225 | } | |
226 | ||
227 | ||
228 | /** | |
229 | * Get member IPAddrHelp | |
230 | * @return IPAddrHelp | |
231 | */ | |
232 | IPAddrHelper::Ptr Serviceholder::get_ip_addr_helper() const | |
233 | { | |
234 | return IPAddrHelp; | |
235 | } |