diff options
Diffstat (limited to 'src/newhelp/chkhelp.c')
-rw-r--r-- | src/newhelp/chkhelp.c | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/newhelp/chkhelp.c b/src/newhelp/chkhelp.c new file mode 100644 index 0000000..3e4f4ad --- /dev/null +++ b/src/newhelp/chkhelp.c @@ -0,0 +1,348 @@ +/* + * + * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * check help files build by newhelp + * + * Usage: + * chkhelp helpfile metricname ... + */ + +#include "pmapi.h" +#include "impl.h" +#include "pmda.h" + +#define VERSION 2 +static int version = VERSION; + +static int handle; + +/* + * Note: these two are from libpcp_pmda/src/help.c + */ +typedef struct { + pmID pmid; + __uint32_t off_oneline; + __uint32_t off_text; +} help_idx_t; + +typedef struct { + int dir_fd; + int pag_fd; + int numidx; + help_idx_t *index; + char *text; + int textlen; +} help_t; + +static int +next(int *ident, int *type) +{ + static help_t *hp = NULL; + static int nextidx; + pmID pmid; + __pmID_int *pi = (__pmID_int *)&pmid; + extern void *__pmdaHelpTab(void); + + if (hp == NULL) { + hp = (help_t *)__pmdaHelpTab(); + /* + * Note, skip header and version info at index[0] + */ + nextidx = 1; + } + + if (nextidx > hp->numidx) + return 0; + + pmid = hp->index[nextidx].pmid; + nextidx++; + + if (pi->flag == 0) { + /* real PMID */ + *ident = (int)pmid; + *type = 1; + } + else { + /* special hack, this is encoding a domain id, not a PMID */ + pi->flag = 0; + *ident = (int)pmid; + *type = 2; + } + + return 1; +} + + +/* + * with -e come here for every metric in the PMNS ... + */ +void +dometric(const char *name) +{ + int sts; + pmID pmid; + char *tp; + + sts = pmLookupName(1, (char **)&name, &pmid); + if (sts < 0) { + fprintf(stderr, "pmLookupName: failed for \"%s\": %s\n", name, pmErrStr(sts)); + return; + } + if (sts == 0) { + fprintf(stderr, "pmLookupName: failed for \"%s\"\n", name); + return; + } + + tp = pmdaGetHelp(handle, pmid, PM_TEXT_ONELINE); + if (tp != NULL) + return; + tp = pmdaGetHelp(handle, pmid, PM_TEXT_HELP); + if (tp != NULL) + return; + + /* no help text, report metric */ + printf("%s\n", name); +} + +int +main(int argc, char **argv) +{ + int sts; + int c; + int help = 0; + int oneline = 0; + char *pmnsfile = PM_NS_DEFAULT; + int errflag = 0; + int aflag = 0; + int eflag = 0; + int allpmid = 0; + int allindom = 0; + char *filename; + char *tp; + char *name; + int id; + int next_type; + char *endnum; + + __pmSetProgname(argv[0]); + + while ((c = getopt(argc, argv, "D:eHin:Opv:?")) != EOF) { + switch (c) { + + case 'D': /* debug flag */ + sts = __pmParseDebug(optarg); + if (sts < 0) { + fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n", + pmProgname, optarg); + errflag++; + } + else + pmDebug |= sts; + break; + + case 'e': /* help text exists? */ + eflag = 1; + break; + + case 'H': /* help text */ + help = 1; + break; + + case 'i': + aflag++; + allindom = 1; + break; + + case 'n': /* alternative namespace file */ + pmnsfile = optarg; + break; + + case 'O': /* oneline text */ + oneline = 1; + break; + + case 'p': + aflag++; + allpmid = 1; + break; + + case 'v': /* version 2 only these days */ + version = (int)strtol(optarg, &endnum, 10); + if (*endnum != '\0') { + fprintf(stderr, "%s: -v requires numeric argument\n", pmProgname); + errflag++; + } + if (version != 2) { + fprintf(stderr + ,"%s: deprecated option - only version 2 is supported\n" + , pmProgname); + errflag++; + } + break; + + case '?': + default: + errflag++; + break; + } + } + + if (optind == argc) { + fprintf(stderr, "%s: missing helpfile argument\n\n", pmProgname); + errflag = 1; + } + + if (aflag && optind < argc-1) { + fprintf(stderr, "%s: metricname arguments cannot be used with -i or -p\n\n", + pmProgname); + errflag = 1; + } + + if (aflag == 0 && optind == argc-1 && oneline+help != 0) { + fprintf(stderr, "%s: -O or -H require metricname arguments or -i or -p\n\n", + pmProgname); + errflag = 1; + } + + if (eflag && (allpmid || allindom)) { + fprintf(stderr, "%s: -e cannot be used with -i or -p\n\n", + pmProgname); + errflag = 1; + } + + if (errflag || optind >= argc) { + fprintf(stderr, +"Usage: %s helpfile\n" +" %s [options] helpfile [metricname ...]\n" +"\n" +"Options:\n" +" -e exists check, only report metrics with no help text\n" +" -H display verbose help text\n" +" -i process all the instance domains\n" +" -n pmnsfile use an alternative PMNS\n" +" -O display the one line help summary\n" +" -p process all the metrics (PMIDs)\n" +" -v version deprecated (only version 2 format supported)\n" +"\n" +"No options implies silently check internal integrity of the helpfile.\n", + pmProgname, pmProgname); + exit(1); + } + + filename = argv[optind++]; + if ((handle = pmdaOpenHelp(filename)) < 0) { + fprintf(stderr, "pmdaOpenHelp: failed to open \"%s\": ", filename); + if (handle == -EINVAL) + fprintf(stderr, "Bad format, not version %d PCP help text\n", version); + else + fprintf(stderr, "%s\n", pmErrStr(handle)); + exit(1); + } + + if ((sts = pmLoadNameSpace(pmnsfile)) < 0) { + fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(sts)); + exit(1); + } + + if (help + oneline == 0 && (optind < argc || aflag)) + /* if metric names, -p or -i => -O is default */ + oneline = 1; + + if (optind == argc && aflag == 0) + /* no metric names, process all entries */ + aflag = 1; + + if (eflag) { + if (optind == argc) + sts = pmTraversePMNS("", dometric); + if (sts < 0) + fprintf(stderr, "Error: pmTraversePMNS(\"\", ...): %s\n", pmErrStr(sts)); + else { + for ( ; optind < argc; optind++) { + sts = pmTraversePMNS(argv[optind], dometric); + if (sts < 0) + fprintf(stderr, "Error: pmTraversePMNS(\"%s\", ...): %s\n", argv[optind], pmErrStr(sts)); + } + } + exit(0); + } + + while (optind < argc || aflag) { + if (aflag) { + if (next(&id, &next_type) == 0) + break; +#ifdef PCP_DEBUG + if ((pmDebug & DBG_TRACE_APPL0) && allindom+allpmid == 0) + fprintf(stderr, "next_type=%d id=0x%x\n", next_type, id); +#endif + if (next_type == 2) { + if (!allindom) + continue; + printf("\nInDom %s:", pmInDomStr((pmInDom)id)); + } + else { + char *p; + if (!allpmid) + continue; + + printf("\nPMID %s", pmIDStr((pmID)id)); + sts = pmNameID(id, &p); + if (sts == 0) { + printf(" %s", p); + free(p); + } + putchar(':'); + } + } + else { + next_type = 1; + name = argv[optind++]; + if ((sts = pmLookupName(1, &name, (pmID *)&id)) < 0) { + printf("\n%s: %s\n", name, pmErrStr(sts)); + continue; + } + if (id == PM_ID_NULL) { + printf("\n%s: unknown metric\n", name); + continue; + } + printf("\nPMID %s %s:", pmIDStr((pmID)id), name); + } + + if (oneline) { + if (next_type == 1) + tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_ONELINE); + else + tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_ONELINE); + if (tp != NULL) + printf(" %s", tp); + putchar('\n'); + } + + if (help) { + if (next_type == 1) + tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_HELP); + else + tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_HELP); + if (tp != NULL && *tp) + printf("%s\n", tp); + } + + } + + return 0; +} |