For extending the command parser's struct option array, there is xtables_merge_options() and xtables_options_xfrm(). Since their bodies were almost identical, make the latter a wrapper of the former by transforming the passed struct xt_option_entry array into a temporary struct option one before handing over. Signed-off-by: Phil Sutter <phil@xxxxxx> --- libxtables/xtoptions.c | 51 +++++++----------------------------------- 1 file changed, 8 insertions(+), 43 deletions(-) diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c index b16bbfbe32311..0667315ceccf8 100644 --- a/libxtables/xtoptions.c +++ b/libxtables/xtoptions.c @@ -73,56 +73,21 @@ struct option * xtables_options_xfrm(struct option *orig_opts, struct option *oldopts, const struct xt_option_entry *entry, unsigned int *offset) { - unsigned int num_orig, num_old = 0, num_new, i; + int num_new, i; struct option *merge, *mp; - if (entry == NULL) - return oldopts; - for (num_orig = 0; orig_opts[num_orig].name != NULL; ++num_orig) - ; - if (oldopts != NULL) - for (num_old = 0; oldopts[num_old].name != NULL; ++num_old) - ; for (num_new = 0; entry[num_new].name != NULL; ++num_new) ; - /* - * Since @oldopts also has @orig_opts already (and does so at the - * start), skip these entries. - */ - if (oldopts != NULL) { - oldopts += num_orig; - num_old -= num_orig; - } - - merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1)); - if (merge == NULL) - return NULL; - - /* Let the base options -[ADI...] have precedence over everything */ - memcpy(merge, orig_opts, sizeof(*mp) * num_orig); - mp = merge + num_orig; - - /* Second, the new options */ - xt_params->option_offset += XT_OPTION_OFFSET_SCALE; - *offset = xt_params->option_offset; - - for (i = 0; i < num_new; ++i, ++mp, ++entry) { - mp->name = entry->name; - mp->has_arg = entry->type != XTTYPE_NONE; - mp->flag = NULL; - mp->val = entry->id + *offset; - } - - /* Third, the old options */ - if (oldopts != NULL) { - memcpy(mp, oldopts, sizeof(*mp) * num_old); - mp += num_old; + mp = xtables_calloc(num_new, sizeof(*mp)); + for (i = 0; i < num_new; i++) { + mp[i].name = entry[i].name; + mp[i].has_arg = entry[i].type != XTTYPE_NONE; + mp[i].val = entry[i].id; } - xtables_free_opts(0); + merge = xtables_merge_options(orig_opts, oldopts, mp, offset); - /* Clear trailing entry */ - memset(mp, 0, sizeof(*mp)); + free(mp); return merge; } -- 2.41.0