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