diff --git a/src/include/pcp/impl.h b/src/include/pcp/impl.h index ad03d3f..c4e2b01 100644 --- a/src/include/pcp/impl.h +++ b/src/include/pcp/impl.h @@ -1186,6 +1186,13 @@ extern int __pmAbsolutePath(char *); extern int __pmPathSeparator(); /* + * discover configurable features of the shared libraries + */ +typedef void (*__pmAPIConfigCallback)(const char *, const char *); +extern void __pmAPIConfig(__pmAPIConfigCallback); +extern const char *__pmGetAPIConfig(const char *); + +/* * AF - general purpose asynchronous event management routines */ extern int __pmAFregister(const struct timeval *, void *, void (*)(int, void *)); diff --git a/src/libpcp/src/check-statics b/src/libpcp/src/check-statics index e53da86..bdd6e04 100755 --- a/src/libpcp/src/check-statics +++ b/src/libpcp/src/check-statics @@ -78,6 +78,7 @@ checksum.o config.o [SDR] ?__pmNativeConfig # const b state.[0-9]* # guarded by __pmLock_libpcp mutex + d features # const connectlocal.o b atexit_installed.[0-9]* # guarded by __pmLock_libpcp mutex b buffer.[0-9]* # assert safe, see notes in connectlocal.c diff --git a/src/libpcp/src/config.c b/src/libpcp/src/config.c index b37beb2..504cc75 100644 --- a/src/libpcp/src/config.c +++ b/src/libpcp/src/config.c @@ -262,3 +262,49 @@ pmGetConfig(const char *name) PM_UNLOCK(__pmLock_libpcp); return val; } + +/* + * Details of runtime features available in the built libpcp + */ + +#if defined(HAVE_SECURE_SOCKETS) +#define PM_SECURE_SOCKETS 1 +#else +#define PM_SECURE_SOCKETS 0 +#endif +#define STRINGIFY(s) #s +#define TO_STRING(s) STRINGIFY(s) + +static const struct { + const char * feature; + const char * state; +} features[] = { + { "pmapi_version", TO_STRING(PMAPI_VERSION) }, + { "multi_threaded", TO_STRING(PM_MULTI_THREADED) }, + { "fault_injection", TO_STRING(PM_FAULT_INJECTION) }, + { "secure_sockets", TO_STRING(PM_SECURE_SOCKETS) }, +}; + +void +__pmAPIConfig(__pmAPIConfigCallback formatter) +{ + int i; + + for (i = 0; i < sizeof(features)/sizeof(features[0]); i++) { + if (pmDebug & DBG_TRACE_CONFIG) + fprintf(stderr, "__pmAPIConfig: %s=%s\n", + features[i].feature, features[i].state); + formatter(features[i].feature, features[i].state); + } +} + +const char * +__pmGetAPIConfig(const char *name) +{ + int i; + + for (i = 0; i < sizeof(features)/sizeof(features[0]); i++) + if (strcasecmp(name, features[i].feature) == 0) + return features[i].state; + return NULL; +} diff --git a/src/pmconfig/pmconfig.c b/src/pmconfig/pmconfig.c index df5b158..565a901 100644 --- a/src/pmconfig/pmconfig.c +++ b/src/pmconfig/pmconfig.c @@ -16,7 +16,7 @@ #include "impl.h" void -formatter(char *var, char *prefix, char *val) +env_formatter(char *var, char *prefix, char *val) { char *v; @@ -28,24 +28,37 @@ formatter(char *var, char *prefix, char *val) printf("%s=%s\n", var, v); } +void +api_formatter(const char *var, const char *val) +{ + if (!val || val[0] == '\0') + printf("%s=false\n", var); + else + printf("%s=%s\n", var, val); +} + int main(int argc, char **argv) { int c; int errflag = 0; int sflag = 0; + int Lflag = 0; __pmSetProgname(argv[0]); - while ((c = getopt(argc, argv, "als")) != EOF) { + while ((c = getopt(argc, argv, "alLs")) != EOF) { switch (c) { - case 'a': /* show all, defualt (unmodified) dump format */ + case 'a': /* show all, default (unmodified) list format */ case 'l': sflag = 0; break; - case 's': /* show all, guarded format for shell expansion */ + case 's': /* show all, guarded format for shell expansion */ sflag = 1; break; + case 'L': + Lflag = 1; + break; case '?': default: errflag++; @@ -59,6 +72,7 @@ main(int argc, char **argv) \n\ Options:\n\ -a | -l show all, unmodified format (default)\n\ + -L show library features instead of environment\n\ -s show all, quoted format for shell expansion\n", pmProgname); exit(1); @@ -67,17 +81,28 @@ Options:\n\ if (optind >= argc) { if (sflag) putenv("SHELL=/bin/sh"); - __pmConfig(formatter); + if (Lflag) + __pmAPIConfig(api_formatter); + else + __pmConfig(env_formatter); } else if (sflag) { putenv("SHELL=/bin/sh"); - for (c = optind; c < argc; c++) - printf("export %s=${%s:-\"%s\"}\n", argv[c], argv[c], + if (Lflag) + for (c = optind; c < argc; c++) + printf("export %s=${%s:-\"%s\"}\n", argv[c], argv[c], + __pmGetAPIConfig(argv[c])); + else + for (c = optind; c < argc; c++) + printf("export %s=${%s:-\"%s\"}\n", argv[c], argv[c], pmGetConfig(argv[c])); } - else { + else if (Lflag) + for (c = optind; c < argc; c++) + printf("%s=%s\n", argv[c], __pmGetAPIConfig(argv[c])); + else for (c = optind; c < argc; c++) printf("%s=%s\n", argv[c], pmGetConfig(argv[c])); - } + exit(0); }