1 /*
2 * mavis_glue.c
3 * (C)1998-2011 by Marc Huber <Marc.Huber@web.de>
4 * All rights reserved.
5 *
6 * Glue code and public interface functions for MAVIS modules.
7 *
8 * $Id: mavis_glue.c,v 1.26 2015/03/14 06:11:28 marc Exp marc $
9 *
10 */
11
12 static const char mavis_glue_rcsid[] __attribute__ ((used)) = "$Id: mavis_glue.c,v 1.26 2015/03/14 06:11:28 marc Exp marc $";
13
14 #ifdef DEBUG
15 #undef DebugIn
16 #undef DebugOut
17 #define DebugIn(A) Debug ((A, "+ "MAVIS_name":%s\n", __func__))
18 #define DebugOut(A) Debug ((A, "- "MAVIS_name":%s\n", __func__))
19 #endif
20
21 #include "log.h"
22 #include "misc/version.h"
23
Mavis_init(mavis_ctx * mcx)24 static int Mavis_init(mavis_ctx * mcx)
25 {
26 int result = MAVIS_INIT_OK;
27 #ifdef HAVE_mavis_init_out
28 int tmp_result = MAVIS_INIT_OK;
29 #endif
30 DebugIn(DEBUG_MAVIS);
31
32 mavis_check_version(VERSION);
33
34 #ifdef HAVE_mavis_init_in
35 result = mavis_init_in(mcx);
36 #endif
37
38 if (mcx->down)
39 result = mcx->down->init(mcx->down);
40
41 #ifdef HAVE_mavis_init_out
42 tmp_result = mavis_init_out(mcx);
43 if (result == MAVIS_INIT_OK)
44 result = tmp_result;
45 #endif
46
47 Debug((DEBUG_MAVIS, "- %s = %d\n", __func__, result));
48 return result;
49 }
50
Mavis_drop(mavis_ctx * mcx)51 static void *Mavis_drop(mavis_ctx * mcx)
52 {
53 void *handle = NULL;
54 DebugIn(DEBUG_MAVIS);
55
56 #ifdef HAVE_mavis_drop_in
57 mavis_drop_in(mcx);
58 #endif
59
60 if (mcx->down)
61 dlclose(mcx->down->drop(mcx->down));
62
63 #ifdef HAVE_mavis_drop_out
64 mavis_drop_out(mcx);
65 #endif
66
67 mavis_script_drop(&mcx->script_in);
68 mavis_script_drop(&mcx->script_out);
69
70 av_free(mcx->ac_bak);
71 mcx->ac_bak = NULL;
72
73 handle = mcx->handle;
74
75 free(mcx);
76
77 DebugOut(DEBUG_MAVIS);
78 return handle;
79 }
80
Mavis_parse(mavis_ctx * mcx,struct sym * sym,char * id)81 static int Mavis_parse(mavis_ctx * mcx, struct sym *sym, char *id)
82 {
83 int result = MAVIS_CONF_ERR;
84 DebugIn(DEBUG_MAVIS);
85
86 #ifdef HAVE_mavis_parse_in
87 if (!strcmp(id, mcx->identifier))
88 result = mavis_parse_in(mcx, sym);
89 else
90 #endif
91 if (mcx->down) {
92 result = mcx->down->parse(mcx->down, sym, id);
93 if (result != MAVIS_CONF_OK)
94 result = MAVIS_CONF_ERR;
95 }
96
97 Debug((DEBUG_MAVIS, "- %s = %d\n", __func__, result));
98 return result;
99 }
100
Mavis_send(mavis_ctx * mcx,av_ctx ** ac)101 static int Mavis_send(mavis_ctx * mcx, av_ctx ** ac)
102 {
103 int result = MAVIS_DOWN;
104
105 DebugIn(DEBUG_MAVIS);
106
107 if (mcx->ac_bak_required) {
108 if (!mcx->ac_bak)
109 mcx->ac_bak = av_new(NULL, NULL);
110 av_copy(mcx->ac_bak, *ac);
111 }
112
113 if (mcx->script_in) {
114 switch (mavis_script_eval(mcx, *ac, mcx->script_in)) {
115 case S_skip:
116 break;
117 case S_return:
118 if (mcx->script_out)
119 mavis_script_eval(mcx, *ac, mcx->script_out);
120 return MAVIS_FINAL;
121 default:;
122 #ifdef HAVE_mavis_send_in
123 result = mavis_send_in(mcx, ac);
124 #endif
125 }
126 }
127 #ifdef HAVE_mavis_send_in
128 else
129 result = mavis_send_in(mcx, ac);
130 #endif
131
132 if (result == MAVIS_DOWN && mcx->down)
133 result = mcx->down->send(mcx->down, ac);
134
135 #ifdef HAVE_mavis_recv_out
136 if (result == MAVIS_FINAL)
137 result = mavis_recv_out(mcx, ac);
138 #endif
139
140 if (result == MAVIS_DOWN)
141 result = MAVIS_FINAL;
142
143 if (mcx->script_out && result == MAVIS_FINAL)
144 mavis_script_eval(mcx, *ac, mcx->script_out);
145
146 Debug((DEBUG_MAVIS, "- %s = %d\n", __func__, result));
147 return result;
148 }
149
Mavis_cancel(mavis_ctx * mcx,void * app_ctx)150 static int Mavis_cancel(mavis_ctx * mcx, void *app_ctx)
151 {
152 int result = MAVIS_DOWN;
153
154 DebugIn(DEBUG_MAVIS);
155
156 #ifdef HAVE_mavis_cancel_in
157 result = mavis_cancel_in(mcx, app_ctx);
158 #endif
159
160 if (result == MAVIS_DOWN && mcx->down)
161 result = mcx->down->cancel(mcx->down, app_ctx);
162
163 if (result == MAVIS_DOWN)
164 result = MAVIS_FINAL;
165
166 Debug((DEBUG_MAVIS, "- %s = %d\n", __func__, result));
167 return result;
168 }
169
Mavis_recv(mavis_ctx * mcx,av_ctx ** ac,void * app_ctx)170 static int Mavis_recv(mavis_ctx * mcx, av_ctx ** ac, void *app_ctx)
171 {
172 int result = MAVIS_DOWN;
173 DebugIn(DEBUG_MAVIS);
174
175 #ifdef HAVE_mavis_recv_in
176 result = mavis_recv_in(mcx, ac, app_ctx);
177 #endif
178
179 if (result == MAVIS_DOWN && mcx->down)
180 result = mcx->down->recv(mcx->down, ac, app_ctx);
181
182 #ifdef HAVE_mavis_recv_out
183 if (result == MAVIS_FINAL)
184 result = mavis_recv_out(mcx, ac);
185 #endif
186
187 if (result == MAVIS_DOWN)
188 result = MAVIS_FINAL;
189
190 if (mcx->script_out && result == MAVIS_FINAL)
191 mavis_script_eval(mcx, *ac, mcx->script_out);
192
193 Debug((DEBUG_MAVIS, "- %s = %d\n", __func__, result));
194 return result;
195 }
196
Mavis_append(mavis_ctx * mcx,void * m)197 static int Mavis_append(mavis_ctx * mcx, void *m)
198 {
199 if (mcx->down)
200 return mcx->down->append(mcx->down, m);
201 mcx->down = m;
202 return 0;
203 }
204
Mavis_new(void * handle,struct io_context * io,char * id)205 mavis_ctx *Mavis_new(void *handle, struct io_context * io, char *id)
206 {
207 mavis_ctx *mcx = Xcalloc(1, sizeof(mavis_ctx) + strlen(id ? id : MAVIS_name));
208 mcx->handle = handle;
209 mcx->append = Mavis_append;
210 mcx->init = Mavis_init;
211 mcx->drop = Mavis_drop;
212 mcx->send = Mavis_send;
213 mcx->recv = Mavis_recv;
214 mcx->parse = Mavis_parse;
215 mcx->cancel = Mavis_cancel;
216 mcx->io = io;
217 strcpy(mcx->identifier, id ? id : MAVIS_name);
218 #ifdef HAVE_mavis_new
219 mavis_new(mcx);
220 #endif
221 return mcx;
222 }
223