1 /*****
2 *
3 * Copyright (C) 2009-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoannv@gmail.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23 
24 #include <iostream>
25 
26 #include <string.h>
27 #include <prelude.h>
28 #include <idmef-path.h>
29 #include <idmef-message-print.h>
30 #include <idmef-object-prv.h>
31 
32 #include "prelude-error.hxx"
33 #include "idmef-path.hxx"
34 #include "idmef.hxx"
35 
36 using namespace Prelude;
37 
38 
IDMEF()39 IDMEF::IDMEF() : _object(NULL)
40 {
41         int ret;
42 
43         ret = idmef_message_new((idmef_message_t **) &_object);
44         if ( ret < 0 )
45                 throw PreludeError(ret);
46 }
47 
48 
IDMEF(const IDMEF & idmef)49 IDMEF::IDMEF(const IDMEF &idmef)
50 {
51         _object = (idmef._object) ? idmef_object_ref(idmef._object) : NULL;
52 }
53 
54 
IDMEF(idmef_object_t * object)55 IDMEF::IDMEF(idmef_object_t *object)
56 {
57         _object = object;
58 }
59 
60 
~IDMEF()61 IDMEF::~IDMEF()
62 {
63         if ( _object )
64                 idmef_object_destroy(_object);
65 }
66 
set(const char * path,const std::vector<IDMEF> & value)67 void IDMEF::set(const char *path, const std::vector<IDMEF> &value)
68 {
69         IDMEFPath(*this, path).set(*this, value);
70 }
71 
72 
set(const char * path,IDMEF * value)73 void IDMEF::set(const char *path, IDMEF *value)
74 {
75         IDMEFPath(*this, path).set(*this, value);
76 }
77 
78 
set(const char * path,const std::vector<IDMEFValue> & value)79 void IDMEF::set(const char *path, const std::vector<IDMEFValue> &value)
80 {
81         IDMEFPath(*this, path).set(*this, value);
82 }
83 
84 
set(const char * path,IDMEFValue * value)85 void IDMEF::set(const char *path, IDMEFValue *value)
86 {
87         IDMEFPath(*this, path).set(*this, value);
88 }
89 
90 
set(const char * path,IDMEFValue & value)91 void IDMEF::set(const char *path, IDMEFValue &value)
92 {
93         IDMEFPath(*this, path).set(*this, &value);
94 }
95 
96 
set(const char * path,const std::string & value)97 void IDMEF::set(const char *path, const std::string &value)
98 {
99         IDMEFPath(*this, path).set(*this, value);
100 }
101 
102 
set(const char * path,const char * value)103 void IDMEF::set(const char *path, const char *value)
104 {
105         IDMEFPath(*this, path).set(*this, value);
106 }
107 
108 
set(const char * path,int32_t value)109 void IDMEF::set(const char *path, int32_t value)
110 {
111         IDMEFPath(*this, path).set(*this, value);
112 }
113 
114 
set(const char * path,int64_t value)115 void IDMEF::set(const char *path, int64_t value)
116 {
117         IDMEFPath(*this, path).set(*this, value);
118 }
119 
120 
set(const char * path,uint64_t value)121 void IDMEF::set(const char *path, uint64_t value)
122 {
123         IDMEFPath(*this, path).set(*this, value);
124 }
125 
126 
set(const char * path,float value)127 void IDMEF::set(const char *path, float value)
128 {
129         IDMEFPath(*this, path).set(*this, value);
130 }
131 
132 
set(const char * path,double value)133 void IDMEF::set(const char *path, double value)
134 {
135         IDMEFPath(*this, path).set(*this, value);
136 }
137 
138 
set(const char * path,IDMEFTime & value)139 void IDMEF::set(const char *path, IDMEFTime &value)
140 {
141         IDMEFPath(*this, path).set(*this, value);
142 }
143 
144 
get(const char * path)145 IDMEFValue IDMEF::get(const char *path)
146 {
147         return IDMEFPath(*this, path).get(*this);
148 }
149 
150 
operator ==(const IDMEF * idmef)151 int IDMEF::operator == (const IDMEF *idmef)
152 {
153         if ( ! idmef )
154                 return 0;
155 
156         if ( _object == idmef->_object )
157                 return 1;
158 
159         return idmef_object_compare(_object, idmef->_object) == 0 ? 1 : 0;
160 }
161 
162 
clone()163 IDMEF IDMEF::clone()
164 {
165         int ret;
166         idmef_object_t *clone;
167 
168         ret = idmef_object_clone(_object, &clone);
169         if ( ret < 0 )
170                 throw PreludeError(ret);
171 
172         return IDMEF(clone);
173 }
174 
175 
getId() const176 idmef_class_id_t IDMEF::getId() const
177 {
178         return _object->_idmef_object_id;
179 }
180 
181 
toString() const182 const std::string IDMEF::toString() const
183 {
184         int ret;
185         std::string str;
186         prelude_io_t *fd;
187 
188         ret = prelude_io_new(&fd);
189         if ( ret < 0 )
190                 throw PreludeError(ret);
191 
192         prelude_io_set_buffer_io(fd);
193         idmef_object_print(_object, fd);
194 
195         str.assign((const char *) prelude_io_get_fdptr(fd), prelude_io_pending(fd));
196 
197         prelude_io_close(fd);
198         prelude_io_destroy(fd);
199 
200         return str;
201 }
202 
203 
204 
ostream_write(prelude_msgbuf_t * fd,prelude_msg_t * msg)205 static int ostream_write(prelude_msgbuf_t *fd, prelude_msg_t *msg)
206 {
207         std::ostream *os = (std::ostream *) prelude_msgbuf_get_data(fd);
208 
209         os->write((const char *)prelude_msg_get_message_data(msg), prelude_msg_get_len(msg));
210         prelude_msg_recycle(msg);
211 
212         return 0;
213 }
214 
215 
istream_read(prelude_io_t * fd,void * buf,size_t size)216 static ssize_t istream_read(prelude_io_t *fd, void *buf, size_t size)
217 {
218         std::istream *is = (std::istream *) prelude_io_get_fdptr(fd);
219 
220         is->read((char *) buf, size);
221         return is->gcount();
222 }
223 
224 
225 
_genericRead(ssize_t (read_cb)(prelude_io_t * fd,void * buf,size_t size),void * fd_data)226 void IDMEF::_genericRead(ssize_t (read_cb)(prelude_io_t *fd, void *buf, size_t size), void *fd_data)
227 {
228         int ret;
229         prelude_io_t *fd;
230         prelude_msg_t *msg = NULL;
231 
232         if ( this->_object->_idmef_object_id != IDMEF_CLASS_ID_MESSAGE )
233                 throw PreludeError("read operation only supported on root IDMEF object");
234 
235         ret = prelude_io_new(&fd);
236         if ( ret < 0 )
237                 throw PreludeError(ret);
238 
239         prelude_io_set_fdptr(fd, fd_data);
240         prelude_io_set_read_callback(fd, read_cb);
241 
242         ret = prelude_msg_read(&msg, fd);
243         prelude_io_destroy(fd);
244         if ( ret < 0 )
245                 throw PreludeError(ret);
246 
247         ret = idmef_message_read((idmef_message_t *) this->_object, msg);
248         if ( ret < 0 ) {
249                 prelude_msg_destroy(msg);
250                 throw PreludeError(ret);
251         }
252 
253         idmef_message_set_pmsg((idmef_message_t *) this->_object, msg);
254 }
255 
256 
operator >>(std::istream & is,Prelude::IDMEF & idmef)257 std::istream &operator >>(std::istream &is, Prelude::IDMEF &idmef)
258 {
259         idmef._genericRead(istream_read, &is);
260         return is;
261 }
262 
263 
264 
_genericWrite(int (write_cb)(prelude_msgbuf_t * msgbuf,prelude_msg_t * msg),void * fd_data) const265 size_t IDMEF::_genericWrite(int (write_cb)(prelude_msgbuf_t *msgbuf, prelude_msg_t *msg), void *fd_data) const
266 {
267         int ret;
268         prelude_msgbuf_t *fd;
269 
270         if ( this->_object->_idmef_object_id != IDMEF_CLASS_ID_MESSAGE )
271                 throw PreludeError("write operation only supported on root IDMEF object");
272 
273         ret = prelude_msgbuf_new(&fd);
274         if ( ret < 0 )
275                 throw PreludeError(ret);
276 
277         prelude_msgbuf_set_data(fd, fd_data);
278         prelude_msgbuf_set_callback(fd, write_cb);
279 
280         ret = idmef_message_write((idmef_message_t *) this->_object, fd);
281         if ( ret < 0 ) {
282                 prelude_msgbuf_destroy(fd);
283                 throw PreludeError(ret);
284         }
285 
286         prelude_msgbuf_destroy(fd);
287         return ret;
288 }
289 
290 
operator <<(std::ostream & os,const IDMEF & idmef)291 std::ostream &operator <<(std::ostream &os, const IDMEF &idmef)
292 {
293         idmef._genericWrite(ostream_write, &os);
294         return os;
295 }
296 
297 
operator const std::string() const298 IDMEF::operator const std::string() const
299 {
300         return toString();
301 }
302 
303 
operator idmef_object_t*() const304 IDMEF::operator idmef_object_t *() const
305 {
306         return (idmef_object_t *) _object;
307 }
308 
309 
operator =(const IDMEF & idmef)310 IDMEF &IDMEF::operator = (const IDMEF &idmef)
311 {
312         if ( this != &idmef && _object != idmef._object ) {
313                 if ( _object )
314                         idmef_object_destroy(_object);
315 
316                 _object = (idmef._object) ? idmef_object_ref(idmef._object) : NULL;
317         }
318 
319         return *this;
320 }
321