From: Nick Porter Date: Mon, 9 Jun 2025 15:35:53 +0000 (+0100) Subject: Define mruby PairList class and its initialize function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3efdd9e0a1380a52aef7bb9322c85d737dd14e6;p=thirdparty%2Ffreeradius-server.git Define mruby PairList class and its initialize function for holding structural pairs --- diff --git a/src/modules/rlm_mruby/mruby.c b/src/modules/rlm_mruby/mruby.c index 7c34b1a04cb..9344f298ad1 100644 --- a/src/modules/rlm_mruby/mruby.c +++ b/src/modules/rlm_mruby/mruby.c @@ -132,3 +132,66 @@ static mrb_value mruby_ruby_pair_object(mrb_state *mrb, struct RClass *klass, mr return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_ruby_pair_type, (void *)pair)); } +/** Associate C structure with Ruby object representing a pair + * + * Will be called with 5 or 6 arguments + * - a pointer to the module instance + * - a pointer to the request + * - a pointer to the dictionary attribute for the pair + * - the instance number of the pair + * - a pointer to the real pair (if it exists) + * - (optional) the parent pair C structure + */ +static mrb_value mruby_pair_init(mrb_state *mrb, mrb_value self) +{ + mruby_pair_t *pair, *parent = NULL; + rlm_mruby_t const *inst; + request_t *request; + fr_dict_attr_t const *da; + mrb_int idx; + fr_pair_t *vp; + + mrb_get_args(mrb, "dddid|d", + &inst, &mruby_inst_type, + &request, &mruby_request_type, + &da, &mruby_dict_attr_type, + &idx, + &vp, &mruby_value_pair_type, + &parent, &mruby_ruby_pair_type); + + /* + * Apparently `initialize` can be called more than once in some + * scenarios, so it is best practice to clear up any old data first + */ + pair = (mruby_pair_t *)DATA_PTR(self); + if (pair) talloc_free(pair); + + /* + * The C data is talloced off frame ctx so we free correctly. + */ + pair = talloc(unlang_interpret_frame_talloc_ctx(request), mruby_pair_t); + mrb_data_init(self, pair, &mruby_value_pair_type); + + *pair = (mruby_pair_t) { + .inst = inst, + .request = request, + .da = da, + .idx = idx, + .vp = vp, + .parent = parent + }; + + return self; +} + +struct RClass *mruby_pair_list_class(mrb_state *mrb, struct RClass *parent) +{ + struct RClass *pair_list; + + pair_list = mrb_define_class_under(mrb, parent, "PairList", mrb->object_class); + MRB_SET_INSTANCE_TT(pair_list, MRB_TT_DATA); + + mrb_define_method(mrb, pair_list, "initialize", mruby_pair_init, MRB_ARGS_ARG(5,1)); + return pair_list; +} + diff --git a/src/modules/rlm_mruby/rlm_mruby.c b/src/modules/rlm_mruby/rlm_mruby.c index a9211b8277b..317395a2e2b 100644 --- a/src/modules/rlm_mruby/rlm_mruby.c +++ b/src/modules/rlm_mruby/rlm_mruby.c @@ -201,6 +201,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* Define the Request class */ inst->mruby_request = mruby_request_class(mrb, inst->mruby_module); + inst->mruby_pair_list = mruby_pair_list_class(mrb, inst->mruby_module); inst->mruby_ptr = mrb_define_class_under(mrb, inst->mruby_module, "Ptr", mrb->object_class); MRB_SET_INSTANCE_TT(inst->mruby_ptr, MRB_TT_DATA); diff --git a/src/modules/rlm_mruby/rlm_mruby.h b/src/modules/rlm_mruby/rlm_mruby.h index 0a9a5796ffb..51c5586a87b 100644 --- a/src/modules/rlm_mruby/rlm_mruby.h +++ b/src/modules/rlm_mruby/rlm_mruby.h @@ -32,6 +32,7 @@ DIAG_OFF(documentation) #include #include #include +#include #include DIAG_ON(documentation) DIAG_ON(DIAG_UNKNOWN_PRAGMAS) @@ -49,10 +50,12 @@ typedef struct { struct RClass *mruby_module; struct RClass *mruby_request; struct RClass *mruby_ptr; + struct RClass *mruby_pair_list; mrb_value mrubyconf_hash; } rlm_mruby_t; struct RClass *mruby_request_class(mrb_state *mrb, struct RClass *parent); +struct RClass *mruby_pair_list_class(mrb_state *mrb, struct RClass *parent); mrb_value mruby_inst_object(mrb_state *mrb, struct RClass *klass, rlm_mruby_t const *inst); mrb_value mruby_request_object(mrb_state *mrb, struct RClass *klass, request_t *request); mrb_value mruby_value_pair_object(mrb_state *mrb, struct RClass *klass, fr_pair_t *vp);