1 /*****
2 *
3 * Copyright (C) 2005-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoann.v@prelude-ids.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 %begin %{
25 #include "config.h"
26 #include "../../libmissing/glthread/thread.h"
27 %}
28 
29 /*
30  * Conversion not allowed
31  */
32 %ignore *::operator =;
33 %ignore *::operator int() const;
34 %ignore *::operator long() const;
35 %ignore *::operator int32_t() const;
36 %ignore *::operator uint32_t() const;
37 %ignore *::operator int64_t() const;
38 %ignore *::operator uint64_t() const;
39 %ignore *::operator float() const;
40 %ignore *::operator double() const;
41 %ignore *::operator Prelude::IDMEFTime() const;
42 %ignore *::operator const std::string() const;
43 %ignore *::operator const char *() const;
44 
45 
46 %header %{
47 #define TARGET_LANGUAGE_SELF SV *
48 #define TARGET_LANGUAGE_OUTPUT_TYPE SV **
49 %}
50 
51 %fragment("IDMEFValueList_to_SWIG", "header") {
52 int IDMEFValue_to_SWIG(TARGET_LANGUAGE_SELF self, const Prelude::IDMEFValue &result, void *extra, TARGET_LANGUAGE_OUTPUT_TYPE ret);
53 
IDMEFValueList_to_SWIG(TARGET_LANGUAGE_SELF self,const Prelude::IDMEFValue & value,void * extra)54 SV *IDMEFValueList_to_SWIG(TARGET_LANGUAGE_SELF self, const Prelude::IDMEFValue &value, void *extra)
55 {
56         int j = 0, ret;
57         std::vector<Prelude::IDMEFValue> result = value;
58         std::vector<Prelude::IDMEFValue>::const_iterator i;
59 
60         AV *myav;
61         SV *svret, **svs = new SV*[result.size()];
62 
63         for ( i = result.begin(); i != result.end(); i++ ) {
64                 if ( (*i).isNull() ) {
65                         SvREFCNT_inc(& PL_sv_undef);
66                         svs[j++] = &PL_sv_undef;
67                 } else {
68                         ret = IDMEFValue_to_SWIG(self, *i, NULL, &svs[j++]);
69                         if ( ret < 0 )
70                                 return NULL;
71                 }
72         }
73 
74         myav = av_make(result.size(), svs);
75         delete[] svs;
76 
77         svret = newRV_noinc((SV*) myav);
78         sv_2mortal(svret);
79 
80         return svret;
81 }
82 }
83 
84 /* tell squid not to cast void * value */
85 %typemap(in) void *nocast_p {
86         $1 = $input;
87 }
88 
89 %fragment("TransitionFunc", "header") {
90 static SV *__prelude_log_func;
91 static gl_thread_t __initial_thread;
92 
93 
_cb_perl_log(int level,const char * str)94 static void _cb_perl_log(int level, const char *str)
95 {
96         if ( (gl_thread_t) gl_thread_self() != __initial_thread )
97                 return;
98 
99         dSP;
100         ENTER;
101         SAVETMPS;
102 
103         PUSHMARK(SP);
104         XPUSHs(SWIG_From_int(level));
105         XPUSHs(SWIG_FromCharPtr(str));
106         PUTBACK;
107 
108         perl_call_sv(__prelude_log_func, G_VOID);
109 
110         FREETMPS;
111         LEAVE;
112 }
113 
114 
_cb_perl_write(prelude_msgbuf_t * fd,prelude_msg_t * msg)115 static int _cb_perl_write(prelude_msgbuf_t *fd, prelude_msg_t *msg)
116 {
117         ssize_t ret;
118         PerlIO *io = (PerlIO *) prelude_msgbuf_get_data(fd);
119 
120         ret = PerlIO_write(io, (const char *) prelude_msg_get_message_data(msg), prelude_msg_get_len(msg));
121         if ( ret != prelude_msg_get_len(msg) )
122                 return prelude_error_from_errno(errno);
123 
124         prelude_msg_recycle(msg);
125 
126         return 0;
127 }
128 
129 
_cb_perl_read(prelude_io_t * fd,void * buf,size_t size)130 static ssize_t _cb_perl_read(prelude_io_t *fd, void *buf, size_t size)
131 {
132         int ret;
133         PerlIO *io = (PerlIO *) prelude_io_get_fdptr(fd);
134 
135         ret = PerlIO_read(io, buf, size);
136         if ( ret < 0 )
137                 ret = prelude_error_from_errno(errno);
138 
139         else if ( ret == 0 )
140                 ret = prelude_error(PRELUDE_ERROR_EOF);
141 
142         return ret;
143 }
144 };
145 
146 %typemap(in, fragment="TransitionFunc") void (*log_cb)(int level, const char *log) {
147         if ( __prelude_log_func )
148                 SvREFCNT_dec(__prelude_log_func);
149 
150         __prelude_log_func = $input;
151         SvREFCNT_inc($input);
152 
153         $1 = _cb_perl_log;
154 };
155 
156 
157 %exception read(void *nocast_p) {
158         try {
159                 $action
catch(Prelude::PreludeError & e)160         } catch(Prelude::PreludeError &e) {
161                 if ( e.getCode() == PRELUDE_ERROR_EOF )
162                         result = 0;
163                 else
164                         SWIG_exception_fail(SWIG_RuntimeError, e.what());
165         }
166 }
167 
168 
169 %extend Prelude::IDMEF {
write(void * nocast_p)170         void write(void *nocast_p) {
171                 PerlIO *io = IoIFP(sv_2io((SV *) nocast_p));
172                 self->_genericWrite(_cb_perl_write, io);
173         }
174 
read(void * nocast_p)175         int read(void *nocast_p) {
176                 PerlIO *io = IoIFP(sv_2io((SV *) nocast_p));
177                 self->_genericRead(_cb_perl_read, io);
178                 return 1;
179         }
180 }
181 
182 
183 %typemap(out, fragment="IDMEFValue_to_SWIG") Prelude::IDMEFValue {
184         int ret;
185 
186         if ( $1.isNull() ) {
187                 SvREFCNT_inc (& PL_sv_undef);
188                 $result = &PL_sv_undef;
189         } else {
190                 SV *mysv;
191 
192                 ret = IDMEFValue_to_SWIG(NULL, $1, NULL, &mysv);
193                 if ( ret < 0 ) {
194                         std::stringstream s;
195                         s << "IDMEFValue typemap does not handle value of type '" << idmef_value_type_to_string((idmef_value_type_id_t) $1.getType()) << "'";
196                         SWIG_exception_fail(SWIG_ValueError, s.str().c_str());
197                 }
198 
199                 $result = mysv;
200         }
201 
202         argvi++;
203 };
204 
205 
206 %init {
207         STRLEN len;
208         char **argv;
209         int j, argc = 1, ret;
210         AV *pargv = get_av("ARGV", FALSE);
211 
212         __initial_thread = (gl_thread_t) gl_thread_self();
213 
214         ret = av_len(pargv);
215         if ( ret >= 0 )
216                 argc += ret + 1;
217 
218         if ( argc + 1 < 0 )
219                 throw PreludeError("Invalide argc length");
220 
221         argv = (char **) malloc((argc + 1) * sizeof(char *));
222         if ( ! argv )
223                 throw PreludeError("Allocation failure");
224 
225         argv[0] = SvPV(get_sv("0", FALSE), len);
226 
227         for ( j = 0; j < ret + 1; j++ )
228                 argv[j + 1] = SvPV(*av_fetch(pargv, j, FALSE), len);
229 
230         argv[j + 1] = NULL;
231 
232         ret = prelude_init(&argc, argv);
233         if ( ret < 0 ) {
234                 free(argv);
235                 throw PreludeError(ret);
236         }
237 
238         free(argv);
239 }
240