int _last_returned_code = 0;
struct onsend_info* p_onsend=0; /* onsend route send info */
+
+
+/* handle the exit code of a module function call.
+ * (used internally in do_action())
+ * @param h - script handle (h->last_retcode and h->run_flags will be set).
+ * @param ret - module function (v0 or v2) retcode
+ * Side-effects: sets _last_returned_code
+ */
+#define MODF_HANDLE_RETCODE(h, ret) \
+ do { \
+ /* if (unlikely((ret)==0)) (h)->run_flags|=EXIT_R_F; */ \
+ (h)->run_flags |= EXIT_R_F & (((ret) != 0) -1); \
+ (h)->last_retcode=(ret); \
+ _last_returned_code = (h)->last_retcode; \
+ } while(0)
+
+
+
+/* frees parameters converted using MODF_RVE_PARAM_CONVERT() from dst.
+ * (used internally in do_action())
+ * Assumes src is unchanged.
+ * Side-effects: clobbers i (int).
+ */
+#define MODF_RVE_PARAM_FREE(src, dst) \
+ for (i=0; i < (dst)[1].u.number; i++) { \
+ if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.string) { \
+ pkg_free((dst)[i+2].u.string); \
+ (dst)[i+2].u.string = 0; \
+ } \
+ }
+
+
+/* fills dst from src, converting RVE_ST params to STRING_ST.
+ * (used internally in do_action())
+ * @param src - source action_u_t array, as in the action structure
+ * @param dst - destination action_u_t array, will be filled from src.
+ * WARNING: dst must be cleaned when done, use MODULE_RVE_PARAM_FREE()
+ * Side-effects: clobbers i (int), s (str), rv (rvalue*), might jump to error.
+ */
+#define MODF_RVE_PARAM_CONVERT(h, msg, src, dst) \
+ do { \
+ (dst)[1]=(src)[1]; \
+ for (i=0; i < (src)[1].u.number; i++) { \
+ if ((src)[2+i].type == RVE_ST) { \
+ rv=rval_expr_eval((h), (msg), (src)[i+2].u.data); \
+ if (unlikely(rv == 0 || \
+ rval_get_str((h), (msg), &s, rv, 0) < 0)) { \
+ rval_destroy(rv); \
+ ERR("failed to convert RVE to string\n"); \
+ (dst)[1].u.number = i; \
+ MODF_RVE_PARAM_FREE(src, dst); \
+ goto error; \
+ } \
+ (dst)[i+2].type = STRING_ST; \
+ (dst)[i+2].u.string = s.s; \
+ (dst)[i+2].u.str.len = s.len; \
+ rval_destroy(rv); \
+ } else \
+ (dst)[i+2]=(src)[i+2]; \
+ } \
+ } while(0)
+
+
+
+/* call a module function with normal STRING_ST params.
+ * (used internally in do_action())
+ * @param f_type - cmd_function type
+ * @param h
+ * @param msg
+ * @param src - source action_u_t array (e.g. action->val)
+ * @param params... - variable list of parameters, passed to the module
+ * function
+ * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), f,
+ * might jump to error.
+ *
+ */
+#ifdef __SUNPRO_C
+#define MODF_CALL(f_type, h, msg, src, ...) \
+ do { \
+ f=((union cmd_export_u*)(src)[0].u.data)->c.function; \
+ ret=((f_type)f)((msg), __VAR_ARGS__); \
+ MODF_HANDLE_RETCODE(h, ret); \
+ } while (0)
+#else /* ! __SUNPRO_C (gcc, icc a.s.o) */
+#define MODF_CALL(f_type, h, msg, src, params...) \
+ do { \
+ f=((union cmd_export_u*)(src)[0].u.data)->c.function; \
+ ret=((f_type)f)((msg), ## params ); \
+ MODF_HANDLE_RETCODE(h, ret); \
+ } while (0)
+#endif /* __SUNPRO_C */
+
+
+
+/* call a module function with possible RVE params.
+ * (used internally in do_action())
+ * @param f_type - cmd_function type
+ * @param h
+ * @param msg
+ * @param src - source action_u_t array (e.g. action->val)
+ * @param dst - temporary action_u_t array used for conversions. It can be
+ * used for the function parameters. It's contents it's not
+ * valid after the call.
+ * @param params... - variable list of parameters, passed to the module
+ * function
+ * Side-effects: sets ret, clobbers i (int), s (str), rv (rvalue*), f, dst,
+ * might jump to error.
+ *
+ */
+#ifdef __SUNPRO_C
+#define MODF_RVE_CALL(f_type, h, msg, src, dst, ...) \
+ do { \
+ f=((union cmd_export_u*)(src)[0].u.data)->c.function; \
+ MODF_RVE_PARAM_CONVERT(h, msg, src, dst); \
+ ret=((f_type)f)((msg), __VAR_ARGS__); \
+ MODF_HANDLE_RETCODE(h, ret); \
+ /* free strings allocated by us */ \
+ MODF_RVE_PARAM_FREE(src, dst); \
+ } while (0)
+#else /* ! __SUNPRO_C (gcc, icc a.s.o) */
+#define MODF_RVE_CALL(f_type, h, msg, src, dst, params...) \
+ do { \
+ f=((union cmd_export_u*)(src)[0].u.data)->c.function; \
+ MODF_RVE_PARAM_CONVERT(h, msg, src, dst); \
+ ret=((f_type)f)((msg), ## params ); \
+ MODF_HANDLE_RETCODE(h, ret); \
+ /* free strings allocated by us */ \
+ MODF_RVE_PARAM_FREE(src, dst); \
+ } while (0)
+#endif /* __SUNPRO_C */
+
+
/* ret= 0! if action -> end of list(e.g DROP),
> 0 to continue processing next actions
and <0 on error */
struct rval_cache c1;
str s;
void *srevp[2];
+ /* temporary storage space for a struct action.val[] working copy
+ (needed to transform RVE intro STRING before calling module
+ functions). [0] is not used (corresp. to the module export pointer),
+ [1] contains the number of params, and [2..] the param values.
+ We need [1], because some fixup function use it
+ (see fixup_get_param_count()). */
+ static action_u_t mod_f_params[MAX_ACTIONS];
/* reset the value of error to E_UNSPEC so avoid unknowledgable
functions to return with error (status<0) and not setting it
(struct action*)a->val[2].u.data, msg);
}
break;
- case MODULE_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function)f)(msg,
- (char*)a->val[2].u.data,
- (char*)a->val[3].u.data
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ case MODULE0_T:
+ MODF_CALL(cmd_function, h, msg, a->val, 0, 0);
break;
/* instead of using the parameter number, we use different names
* for calls to functions with 3, 4, 5, 6 or variable number of
* parameters due to performance reasons */
+ case MODULE1_T:
+ MODF_CALL(cmd_function, h, msg, a->val,
+ (char*)a->val[2].u.data,
+ 0
+ );
+ break;
+ case MODULE2_T:
+ MODF_CALL(cmd_function, h, msg, a->val,
+ (char*)a->val[2].u.data,
+ (char*)a->val[3].u.data
+ );
+ break;
case MODULE3_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function3)f)(msg,
+ MODF_CALL(cmd_function3, h, msg, a->val,
(char*)a->val[2].u.data,
(char*)a->val[3].u.data,
(char*)a->val[4].u.data
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ );
break;
case MODULE4_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function4)f)(msg,
+ MODF_CALL(cmd_function4, h, msg, a->val,
(char*)a->val[2].u.data,
(char*)a->val[3].u.data,
(char*)a->val[4].u.data,
(char*)a->val[5].u.data
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ );
break;
case MODULE5_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function5)f)(msg,
+ MODF_CALL(cmd_function5, h, msg, a->val,
(char*)a->val[2].u.data,
(char*)a->val[3].u.data,
(char*)a->val[4].u.data,
(char*)a->val[5].u.data,
(char*)a->val[6].u.data
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ );
break;
case MODULE6_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function6)f)(msg,
+ MODF_CALL(cmd_function6, h, msg, a->val,
(char*)a->val[2].u.data,
(char*)a->val[3].u.data,
(char*)a->val[4].u.data,
(char*)a->val[5].u.data,
(char*)a->val[6].u.data,
(char*)a->val[7].u.data
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ );
break;
case MODULEX_T:
- if ( a->val[0].type==MODEXP_ST && a->val[0].u.data &&
- (f=((union cmd_export_u*)a->val[0].u.data)->c.function)){
- ret=((cmd_function_var)f)(msg,
- a->val[1].u.number,
- &a->val[2]
- );
- if (ret==0) h->run_flags|=EXIT_R_F;
- h->last_retcode=ret;
- _last_returned_code = h->last_retcode;
- } else {
- LOG(L_CRIT,"BUG: do_action: bad module call\n");
- goto error;
- }
+ MODF_CALL(cmd_function_var, h, msg, a->val,
+ a->val[1].u.number, &a->val[2]);
+ break;
+ case MODULE1_RVE_T:
+ MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ 0
+ );
+ break;
+ case MODULE2_RVE_T:
+ MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ (char*)mod_f_params[3].u.data
+ );
+ break;
+ case MODULE3_RVE_T:
+ MODF_RVE_CALL(cmd_function3, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ (char*)mod_f_params[3].u.data,
+ (char*)mod_f_params[4].u.data
+ );
+ break;
+ case MODULE4_RVE_T:
+ MODF_RVE_CALL(cmd_function4, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ (char*)mod_f_params[3].u.data,
+ (char*)mod_f_params[4].u.data,
+ (char*)mod_f_params[5].u.data
+ );
+ break;
+ case MODULE5_RVE_T:
+ MODF_RVE_CALL(cmd_function5, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ (char*)mod_f_params[3].u.data,
+ (char*)mod_f_params[4].u.data,
+ (char*)mod_f_params[5].u.data,
+ (char*)mod_f_params[6].u.data
+ );
+ break;
+ case MODULE6_RVE_T:
+ MODF_RVE_CALL(cmd_function6, h, msg, a->val, mod_f_params,
+ (char*)mod_f_params[2].u.data,
+ (char*)mod_f_params[3].u.data,
+ (char*)mod_f_params[4].u.data,
+ (char*)mod_f_params[5].u.data,
+ (char*)mod_f_params[6].u.data,
+ (char*)mod_f_params[7].u.data
+ );
+ break;
+ case MODULEX_RVE_T:
+ MODF_RVE_CALL(cmd_function_var, h, msg, a->val, mod_f_params,
+ a->val[1].u.number, &mod_f_params[2]);
break;
case EVAL_T:
/* only eval the expression to account for possible