commit df1b71b4ffb08376e1c36576d0cb9ba9456cbeba from: Stefan Sperling date: Mon Sep 11 07:04:42 2023 UTC introduce struct ctl2 with backwards compat wrappers The new struct avoids the necessity to cast configuration file test handler arguments from char ** to a char *, such that the char ** pointer can be stored in ctl->args[1]. Such shadowing of variable types results in code that is hard to follow. We can convert daemons one-by-one to fully replace struct ctl eventually. As an example, convert dhcpd handling to struct ctl2 already. Ok tom, chris commit - e05df6135adc342714e1eb0aa52000db39b6010c commit + df1b71b4ffb08376e1c36576d0cb9ba9456cbeba blob - 17256bbabcae936e02f020bc676e43ad55dc1a51 blob + 10708daf18f31248cb47bdfec873ce1807bc56a1 --- commands.c +++ commands.c @@ -1947,6 +1947,7 @@ struct ghs mantab[] = { */ #define ssctl sizeof(struct ctl) +#define ssctl2 sizeof(struct ctl2) Command cmdtab[] = { { "hostname", hostnamehelp, CMPL0 0, 0, hostname, 1, 1, 0, 0 }, { "interface", interfacehelp, CMPL(i) 0, 0, interface, 1, 1, 1, 1 }, @@ -1979,7 +1980,7 @@ Command cmdtab[] = { { "dvmrp", dvmrphelp, CMPL(t) (char **)ctl_dvmrp, ssctl, ctlhandler, 1, 1, 0, 1 }, { "rad", radhelp, CMPL(t) (char **)ctl_rad, ssctl, ctlhandler, 1, 1, 0, 1 }, { "sasync", sasynchelp, CMPL(t) (char **)ctl_sasync, ssctl, ctlhandler, 1, 1, 0, 1 }, - { "dhcp", dhcphelp, CMPL(t) (char **)ctl_dhcp, ssctl, ctlhandler, 1, 1, 0, 1 }, + { "dhcp", dhcphelp, CMPL(t) (char **)ctl_dhcp, ssctl2, ctlhandler, 1, 1, 0, 1 }, { "snmp", snmphelp, CMPL(t) (char **)ctl_snmp, ssctl, ctlhandler, 1, 1, 0, 1 }, { "ldap", ldaphelp, CMPL(t) (char **)ctl_ldap, ssctl, ctlhandler, 1, 1, 0, 1 }, { "smtp", smtphelp, CMPL(t) (char **)ctl_smtp, ssctl, ctlhandler, 1, 1, 0, 1 }, blob - 4011e0f3cb3a14e6359f82f82497db29b47dcd89 blob + 5595248f26d9a4f1057c8112534aad0e2dc3c15b --- ctl.c +++ ctl.c @@ -31,6 +31,33 @@ #include "editing.h" #include "ctl.h" +static inline void +ctl2toctl(struct ctl *ctl, const struct ctl2 *ctl2) +{ + ctl->name = ctl2->name; + ctl->help = ctl2->help; + memcpy(ctl->args, ctl2->args, sizeof(ctl->args)); + if (ctl2->type == T_HANDLER_FILL1) + ctl->args[1] = (char *)ctl2->test_args; + ctl->handler = ctl2->handler; + ctl->flag_x = ctl->flag_x; + ctl->type = ctl->type; +} + +static inline void +daemons2todaemons(struct daemons *daemons, struct ctl *ctl1, + const struct daemons2 *daemons2) +{ + daemons->name = daemons2->name; + daemons->propername = daemons2->propername; + ctl2toctl(ctl1, daemons2->table); + daemons->table = ctl1; + daemons->tmpfile = daemons2->tmpfile; + daemons->mode = daemons2->mode; + daemons->doreload = daemons2->doreload; + daemons->rtablemax = daemons2->rtablemax; +} + /* table variable (for pkill usage) */ static char table[16]; @@ -60,7 +87,6 @@ struct daemons ctl_daemons[] = { { "rad", "rad", ctl_rad, RADCONF_TEMP, 0600, 0, 0 }, { "dvmrp", "DVMRP",ctl_dvmrp, DVMRPCONF_TEMP, 0600, 0, RT_TABLEID_MAX }, { "sasync", "SAsync",ctl_sasync, SASYNCCONF_TEMP,0600, 0, RT_TABLEID_MAX }, -{ "dhcp", "DHCP", ctl_dhcp, DHCPCONF_TEMP, 0600, 0, RT_TABLEID_MAX }, { "snmp", "SNMP", ctl_snmp, SNMPCONF_TEMP, 0600, 0, RT_TABLEID_MAX }, { "sshd", "SSH", ctl_sshd, SSHDCONF_TEMP, 0600, 0, RT_TABLEID_MAX }, { "ntp", "NTP", ctl_ntp, NTPCONF_TEMP, 0600, 0, 0 }, @@ -78,6 +104,10 @@ struct daemons ctl_daemons[] = { { "crontab", "crontab", ctl_crontab, CRONTAB_TEMP, 0600, 0, 0 }, { "scheduler", "scheduler", ctl_crontab, CRONTAB_TEMP, 0600, 0, 0 }, { 0, 0, 0, 0, 0, 0 } +}; + +struct daemons2 ctl_daemons2[] = { +{ "dhcp", "DHCP", ctl_dhcp, DHCPCONF_TEMP, 0600, 0, RT_TABLEID_MAX }, }; /* per-daemon commands, and their C or executable functions */ @@ -383,20 +413,20 @@ struct ctl ctl_nppp[] = { }; /* dhcpd */ -char *ctl_dhcp_test[] = { DHCPD, "-nc", REQTEMP, NULL }; -struct ctl ctl_dhcp[] = { +struct ctl2 ctl_dhcp[] = { { "enable", "enable DHCPd daemon", - { DHCPD, "-c", REQTEMP, "-l", DHCPLEASES, NULL }, NULL, DB_X_ENABLE, - T_EXEC }, + { DHCPD, "-c", REQTEMP, "-l", DHCPLEASES, NULL }, { NULL, }, NULL, + DB_X_ENABLE, T_EXEC }, { "disable", "disable DHCPd daemon", - { PKILL, table, "dhcpd", NULL }, NULL, DB_X_DISABLE, T_EXEC }, + { PKILL, table, "dhcpd", NULL }, { NULL, }, NULL, + DB_X_DISABLE, T_EXEC }, { "edit", "edit,test and stage DHCPd config", - { "dhcp", (char *)ctl_dhcp_test, NULL }, call_editor, 0, + { "dhcp", NULL }, { DHCPD, "-nc", REQTEMP, NULL }, call_editor, 0, T_HANDLER_FILL1 }, { "config-test", "test staged DHCPd config", - { DHCPD, "-nc", REQTEMP, "-l", DHCPLEASES, NULL }, NULL, 0, - T_EXEC }, - { 0, 0, { 0 }, 0, 0, 0 } + { DHCPD, "-nc", REQTEMP, "-l", DHCPLEASES, NULL }, { NULL, }, + NULL, 0, T_EXEC }, + { NULL, NULL, { NULL }, { NULL }, NULL, 0, 0 } }; /* snmpd, snmpctl */ @@ -597,18 +627,35 @@ int ctlhandler(int argc, char **argv, char *modhvar) { struct daemons *daemons; + struct daemons2 *daemons2; struct ctl *x; + struct ctl2 *x2; + struct daemons daemons1; + struct ctl ctl1; char tmpfile[PATH_MAX]; char *step_args[NOPTFILL] = { NULL, NULL, NULL, NULL, NULL, NULL }; char *tmp_args[NOPTFILL] = { NULL, NULL, NULL, NULL, NULL, NULL }; char **fillargs; + char **xargs; + int xtype; + void (*xhandler)(); + int xflag_x; + char **xtest_args = NULL; + memset(&daemons1, 0, sizeof(daemons1)); + /* loop daemon list to find table pointer */ daemons = (struct daemons *) genget(hname, (char **)ctl_daemons, sizeof(struct daemons)); - if (daemons == 0) { - printf("%% Internal error - Invalid argument %s\n", argv[1]); - return 0; + if (daemons == NULL) { + daemons2 = (struct daemons2 *) genget(hname, + (char **)ctl_daemons2, sizeof(struct daemons2)); + if (daemons2 == NULL) { + printf("%% Internal error - Invalid argument %s\n", argv[1]); + return 0; + } + daemons2todaemons(&daemons1, &ctl1, daemons2); + daemons = &daemons1; } else if (Ambiguous(daemons)) { printf("%% Internal error - Ambiguous argument %s\n", argv[1]); return 0; @@ -646,36 +693,59 @@ ctlhandler(int argc, char **argv, char *modhvar) return 0; } - x = (struct ctl *) genget(argv[1], (char **)daemons->table, - sizeof(struct ctl)); - if (x == 0) { - printf("%% Invalid argument %s\n", argv[1]); - return 0; - } else if (Ambiguous(x)) { - printf("%% Ambiguous argument %s\n", argv[1]); - return 0; + if (daemons1.name != NULL) { + x2 = (struct ctl2 *) genget(argv[1], + (char **)daemons2->table, sizeof(struct ctl2)); + if (x2 == NULL) { + printf("%% Invalid argument %s\n", argv[1]); + return 0; + } else if (Ambiguous(x2)) { + printf("%% Ambiguous argument %s\n", argv[1]); + return 0; + } + xargs = x2->args; + xtype = x2->type; + xhandler = x2->handler; + xflag_x = x2->flag_x; + xtest_args = x2->test_args; + } else { + x = (struct ctl *) genget(argv[1], (char **)daemons->table, + sizeof(struct ctl)); + if (x == NULL) { + printf("%% Invalid argument %s\n", argv[1]); + return 0; + } else if (Ambiguous(x)) { + printf("%% Ambiguous argument %s\n", argv[1]); + return 0; + } + xargs = x->args; + xtype = x->type; + xhandler = x->handler; + xflag_x = x->flag_x; + if (x->type == T_HANDLER_FILL1) + xtest_args = (char **)x->args[1]; } - fillargs = step_optreq(x->args, step_args, argc, argv, 2); + fillargs = step_optreq(xargs, step_args, argc, argv, 2); if (fillargs == NULL) return 0; - switch(x->type) { + switch(xtype) { /* fill_tmpfile will return 0 if tmpfile or args are NULL */ case T_HANDLER: /* pointer to handler routine, fill main args */ if (fill_tmpfile(fillargs, tmpfile, tmp_args)) { - (*x->handler)(tmp_args[0], tmp_args[1], tmp_args[2]); + (*xhandler)(tmp_args[0], tmp_args[1], tmp_args[2]); } else { - (*x->handler)(fillargs[0], fillargs[1], fillargs[2]); + (*xhandler)(fillargs[0], fillargs[1], fillargs[2]); } break; case T_HANDLER_FILL1: /* pointer to handler routine, fill args @ args[1] pointer */ - if (fill_tmpfile((char **)fillargs[1], tmpfile, tmp_args)) - (*x->handler)(fillargs[0], tmp_args, fillargs[2]); + if (fill_tmpfile(xtest_args, tmpfile, tmp_args)) + (*xhandler)(fillargs[0], tmp_args, fillargs[2]); else - (*x->handler)(fillargs[0], (char **)fillargs[1], fillargs[2]); + (*xhandler)(fillargs[0], xtest_args, fillargs[2]); break; case T_EXEC: /* command to execute via execv syscall, fill main args */ @@ -686,8 +756,8 @@ ctlhandler(int argc, char **argv, char *modhvar) break; } - if (x->flag_x != 0) { - flag_x("ctl", daemons->name, x->flag_x, NULL); + if (xflag_x != 0) { + flag_x("ctl", daemons->name, xflag_x, NULL); } return 1; @@ -801,22 +871,34 @@ call_editor(char *name, char **args, char *z) int found = 0; char tmpfile[64]; struct daemons *daemons; + struct daemons2 *daemons2; - for (daemons = ctl_daemons; daemons->name != 0; daemons++) + for (daemons = ctl_daemons; daemons->name != 0; daemons++) { if (strncmp(daemons->name, name, strlen(name)) == 0) { found = 1; break; } + } + if (found) { + snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons->tmpfile, + cli_rtable); + edit_file(tmpfile, daemons->mode, daemons->propername, args); + return; + } + for (daemons2 = ctl_daemons2; daemons2->name != 0; daemons2++) { + if (strncmp(daemons2->name, name, strlen(name)) == 0) { + found = 1; + break; + } + } if (!found) { printf("%% call_editor internal error\n"); return; } - - snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons->tmpfile, + snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons2->tmpfile, cli_rtable); - - edit_file(tmpfile, daemons->mode, daemons->propername, args); + edit_file(tmpfile, daemons2->mode, daemons2->propername, args); } static void blob - 23cea48dd84cd5bce7b4c64b2ebd91bbf33f4f0a blob + 8140478bd623a1711ccbe4f587611cde53515ea7 --- ctl.h +++ ctl.h @@ -79,6 +79,16 @@ struct ctl { int type; }; +struct ctl2 { + char *name; + char *help; + char *args[32]; + char *test_args[32]; + void (*handler)(); + int flag_x; + int type; +}; + #define T_HANDLER 1 #define T_HANDLER_FILL1 2 #define T_EXEC 3 @@ -92,7 +102,17 @@ struct daemons { int rtablemax; }; +struct daemons2 { + char *name; + char *propername; + struct ctl2 *table; + char *tmpfile; + mode_t mode; + int doreload; + int rtablemax; +}; + /* tmp config locations */ #define PFCONF_TEMP "/var/run/pf.conf" #define OSPFCONF_TEMP "/var/run/ospfd.conf" @@ -167,7 +187,7 @@ extern struct ctl ctl_ike[]; extern struct ctl ctl_dvmrp[]; extern struct ctl ctl_rad[]; extern struct ctl ctl_sasync[]; -extern struct ctl ctl_dhcp[]; +extern struct ctl2 ctl_dhcp[]; extern struct ctl ctl_snmp[]; extern struct ctl ctl_smtp[]; extern struct ctl ctl_sshd[];