summaryrefslogtreecommitdiff
path: root/src/libpcp_pmda/src/help.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpcp_pmda/src/help.c')
-rw-r--r--src/libpcp_pmda/src/help.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/libpcp_pmda/src/help.c b/src/libpcp_pmda/src/help.c
new file mode 100644
index 0000000..d9d17b8
--- /dev/null
+++ b/src/libpcp_pmda/src/help.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 1995-2003 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License for more details.
+ */
+
+/*
+ * Get help text from files built using newhelp
+ */
+#include "pmapi.h"
+#include "impl.h"
+#include "pmda.h"
+#include <sys/stat.h>
+
+typedef struct { /* beware: this data structure mirrored in chkhelp */
+ pmID pmid;
+ __uint32_t off_oneline;
+ __uint32_t off_text;
+} help_idx_t;
+
+typedef struct { /* beware: this data structure mirrored in chkhelp */
+ int dir_fd;
+ int pag_fd;
+ int numidx;
+ help_idx_t *index;
+ char *text;
+ int textlen;
+} help_t;
+
+static help_t *tab = NULL;
+static int numhelp = 0;
+
+/*
+ * open the help text files and return a handle on success
+ */
+int
+pmdaOpenHelp(char *fname)
+{
+ char pathname[MAXPATHLEN];
+ int sts, size;
+ help_idx_t hdr;
+ help_t *hp;
+ struct stat sbuf;
+
+ for (sts = 0; sts < numhelp; sts++) {
+ if (tab[sts].dir_fd == -1)
+ break;
+ }
+ if (sts == numhelp) {
+ sts = numhelp++;
+ tab = (help_t *)realloc(tab, numhelp * sizeof(tab[0]));
+ if (tab == NULL) {
+ __pmNoMem("pmdaOpenHelp", numhelp * sizeof(tab[0]), PM_RECOV_ERR);
+ numhelp = 0;
+ return -oserror();
+ }
+ }
+ hp = &tab[sts];
+ memset(hp, 0, sizeof(*hp));
+ hp->dir_fd = -1;
+ hp->pag_fd = -1;
+
+ snprintf(pathname, sizeof(pathname), "%s.dir", fname);
+ hp->dir_fd = open(pathname, O_RDONLY);
+ if (hp->dir_fd < 0) {
+ sts = -oserror();
+ goto failed;
+ }
+
+ if (read(hp->dir_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ sts = -EINVAL;
+ goto failed;
+ }
+
+ if (hdr.pmid != 0x50635068 ||
+ (hdr.off_oneline & 0xffff0000) != 0x31320000) {
+ sts = -EINVAL;
+ goto failed;
+ }
+
+ hp->numidx = hdr.off_text;
+ size = (hp->numidx + 1) * sizeof(help_idx_t);
+
+ hp->index = (help_idx_t *)__pmMemoryMap(hp->dir_fd, size, 0);
+ if (hp->index == NULL) {
+ sts = -oserror();
+ goto failed;
+ }
+
+ snprintf(pathname, sizeof(pathname), "%s.pag", fname);
+ hp->pag_fd = open(pathname, O_RDONLY);
+ if (hp->pag_fd < 0) {
+ sts = -oserror();
+ goto failed;
+ }
+ if (fstat(hp->pag_fd, &sbuf) < 0) {
+ sts = -oserror();
+ goto failed;
+ }
+ hp->textlen = (int)sbuf.st_size;
+ hp->text = (char *)__pmMemoryMap(hp->pag_fd, hp->textlen, 0);
+ if (hp->text == NULL) {
+ sts = -oserror();
+ goto failed;
+ }
+ return numhelp - 1;
+
+failed:
+ pmdaCloseHelp(numhelp-1);
+ return sts;
+}
+
+/*
+ * retrieve pmID help text, ...
+ *
+ */
+char *
+pmdaGetHelp(int handle, pmID pmid, int type)
+{
+ int i;
+ help_t *hp;
+
+ if (handle < 0 || handle >= numhelp)
+ return NULL;
+ hp = &tab[handle];
+
+ /* search forwards -- could use binary chop */
+ for (i = 1; i <= hp->numidx; i++) {
+ if (hp->index[i].pmid == pmid) {
+ if (type & PM_TEXT_ONELINE)
+ return &hp->text[hp->index[i].off_oneline];
+ else
+ return &hp->text[hp->index[i].off_text];
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * retrieve pmInDom help text, ...
+ *
+ */
+char *
+pmdaGetInDomHelp(int handle, pmInDom indom, int type)
+{
+ int i;
+ help_t *hp;
+ pmID pmid;
+ __pmID_int *pip = (__pmID_int *)&pmid;
+
+ if (handle < 0 || handle >= numhelp)
+ return NULL;
+ hp = &tab[handle];
+
+ *pip = *((__pmID_int *)&indom);
+ /*
+ * set a bit here to disambiguate pmInDom from pmID
+ * -- this "hack" is shared between here and newhelp/newhelp.c
+ */
+ pip->flag = 1;
+
+ /* search backwards ... pmInDom entries are at the end */
+ for (i = hp->numidx; i >= 1; i--) {
+ if (hp->index[i].pmid == pmid) {
+ if (type & PM_TEXT_ONELINE)
+ return &hp->text[hp->index[i].off_oneline];
+ else
+ return &hp->text[hp->index[i].off_text];
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * this is only here for chkhelp(1) ... export the control data strcuture
+ */
+void *
+__pmdaHelpTab(void)
+{
+ return (void *)tab;
+}
+
+void
+pmdaCloseHelp(int handle)
+{
+ help_t *hp;
+
+ if (handle < 0 || handle >= numhelp)
+ return;
+ hp = &tab[handle];
+
+ if (hp->dir_fd != -1)
+ close(hp->dir_fd);
+ if (hp->pag_fd != -1)
+ close(hp->pag_fd);
+ if (hp->index != NULL)
+ __pmMemoryUnmap((void *)hp->index, (hp->numidx+1) * sizeof(help_idx_t));
+ if (hp->text != NULL)
+ __pmMemoryUnmap(hp->text, hp->textlen);
+
+ hp->textlen = 0;
+ hp->dir_fd = -1;
+ hp->pag_fd = -1;
+ hp->numidx = 0;
+ hp->index = NULL;
+ hp->text = NULL;
+}