M CHANGELOG.md => CHANGELOG.md +4 -0
@@ 5,6 5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+### Added
+- Support listing applets compiled into a multicall `dmon` binary when the
+ `DMON_LIST_MULTICALL_APPLETS` environment variable is set and non-zero.
+
### Changed
- GNU Make is not required anymore, the included `Makefile` now works with
the BSD variant as well, and probably others.
M dmon.rst => dmon.rst +4 -0
@@ 281,6 281,10 @@ variable, if defined. Any command line option can be specified this way.
Arguments read from the environment variable will be prepended to the ones
given in the command line, so they may still be overriden.
+If the ``DMON_LIST_MULTICALL_APPLETS`` is defined and has a non-zero value,
+the list of applets compiled into a multicall binary will be printed out,
+and the program will exit immediately.
+
SEE ALSO
========
M multicall.c => multicall.c +33 -24
@@ 8,44 8,53 @@
#if defined(MULTICALL) && MULTICALL
#include "util.h"
+#include <stdlib.h>
#include <string.h>
+extern int dlog_main(int, char**);
+extern int dmon_main(int, char**);
+extern int drlog_main(int, char**);
+extern int dslog_main(int, char**);
-typedef int (*mainfunc_t)(int, char**);
-#define APPLET_LIST_BEGIN static mainfunc_t choose_applet (const char *name) {
-#define APPLET(_n) if (!strcmp (name, #_n)) return _n ## _main;
-#define APPLET_LIST_END return NULL; }
-
-
-extern int dmon_main (int, char**);
-extern int dlog_main (int, char**);
-extern int dslog_main (int, char**);
-extern int drlog_main (int, char**);
-
-
-APPLET_LIST_BEGIN
- APPLET (dmon)
- APPLET (dlog)
- APPLET (dslog)
- APPLET (drlog)
-APPLET_LIST_END
+static const struct {
+ const char *name;
+ int (*func)(int, char**);
+} applets[] = {
+ { .name = "dmon", .func = dmon_main },
+ { .name = "dlog", .func = dlog_main },
+ { .name = "drlog", .func = drlog_main },
+ { .name = "dslog", .func = dslog_main },
+};
int
-main (int argc, char **argv)
+main(int argc, char **argv)
{
- const char *argv0 = strrchr (argv[0], '/');
- mainfunc_t mainfunc;
-
+ const char *argv0 = strrchr(argv[0], '/');
if (argv0 == NULL)
argv0 = argv[0];
else
argv0++;
- mainfunc = choose_applet (argv0);
+ const char *env = getenv("DMON_LIST_MULTICALL_APPLETS");
+ const bool list = env && *env != '\0' && *env != '0';
+
+ int (*mainfunc)(int, char**) = NULL;
+
+ for (unsigned i = 0; i < sizeof(applets) / sizeof(applets[0]); i++) {
+ if (list) {
+ puts(applets[i].name);
+ } else if (strcmp(argv0, applets[i].name) == 0) {
+ mainfunc = applets[i].func;
+ break;
+ }
+ }
+
+ if (list)
+ return EXIT_SUCCESS;
if (mainfunc == NULL)
- die ("%s: No such applet in multicall binary.\n", argv0);
+ die("%s: No such applet in multicall binary.\n", argv0);
return (*mainfunc)(argc, argv);
}