static int bindkey(KEYMAP **mapp, const char *fname, KCHAR *keys, int kcount) { KEYMAP *curmap = *mapp; KEYMAP *pref_map = NULL; PF funct; int c; if (fname == NULL) funct = rescan; else if (((funct = name_function(fname)) == NULL) ? (pref_map = name_map(fname)) == NULL : funct == NULL) { ewprintf("[No match: %s]", fname); return (FALSE); } while (--kcount) { if (doscan(curmap, c = *keys++, &curmap) != NULL) { if (remap(curmap, c, NULL, NULL) != TRUE) return (FALSE); /* * XXX - Bizzarreness. remap creates an empty KEYMAP * that the last key is supposed to point to. */ curmap = ele->k_prefmap; } } (void)doscan(curmap, c = *keys, NULL); return (remap(curmap, c, funct, pref_map)); }
/* * Do the input for local-set-key, global-set-key and define-key * then call remap to do the work. */ static int dobind(KEYMAP *curmap, const char *p, int unbind) { KEYMAP *pref_map = NULL; PF funct; char bprompt[80], *bufp, *pep; int c, s, n; if (macrodef) { /* * Keystrokes aren't collected. Not hard, but pretty useless. * Would not work for function keys in any case. */ ewprintf("Can't rebind key in macro"); return (FALSE); } if (inmacro) { for (s = 0; s < maclcur->l_used - 1; s++) { if (doscan(curmap, c = CHARMASK(maclcur->l_text[s]), &curmap) != NULL) { if (remap(curmap, c, NULL, NULL) != TRUE) return (FALSE); } } (void)doscan(curmap, c = maclcur->l_text[s], NULL); maclcur = maclcur->l_fp; } else { n = strlcpy(bprompt, p, sizeof(bprompt)); if (n >= sizeof(bprompt)) n = sizeof(bprompt) - 1; pep = bprompt + n; for (;;) { ewprintf("%s", bprompt); pep[-1] = ' '; pep = getkeyname(pep, sizeof(bprompt) - (pep - bprompt), c = getkey(FALSE)); if (doscan(curmap, c, &curmap) != NULL) break; *pep++ = '-'; *pep = '\0'; } } if (unbind) funct = rescan; else { if ((bufp = eread("%s to command: ", bprompt, sizeof(bprompt), EFFUNC | EFNEW, bprompt)) == NULL) return (ABORT); else if (bufp[0] == '\0') return (FALSE); if (((funct = name_function(bprompt)) == NULL) ? (pref_map = name_map(bprompt)) == NULL : funct == NULL) { ewprintf("[No match]"); return (FALSE); } } return (remap(curmap, c, funct, pref_map)); }
int rescan(int f, int n) { int c; KEYMAP *curmap; int i; PF fp = NULL; int md = curbp->b_nmodes; for (;;) { if (ISUPPER(key.k_chars[key.k_count - 1])) { c = TOLOWER(key.k_chars[key.k_count - 1]); curmap = curbp->b_modes[md]->p_map; for (i = 0; i < key.k_count - 1; i++) { if ((fp = doscan(curmap, (key.k_chars[i]), &curmap)) != NULL) break; } if (fp == NULL) { if ((fp = doscan(curmap, c, NULL)) == NULL) while ((fp = doscan(curmap, key.k_chars[key.k_count++] = getkey(TRUE), &curmap)) == NULL) /* nothing */; if (fp != rescan) { if (macrodef && macrocount <= MAXMACRO) macro[macrocount - 1].m_funct = fp; return (mgwrap(fp, f, n)); } } } /* try previous mode */ if (--md < 0) return (ABORT); curmap = curbp->b_modes[md]->p_map; for (i = 0; i < key.k_count; i++) { if ((fp = doscan(curmap, (key.k_chars[i]), &curmap)) != NULL) break; } if (fp == NULL) { while ((fp = doscan(curmap, key.k_chars[i++] = getkey(TRUE), &curmap)) == NULL) /* nothing */; key.k_count = i; } if (fp != rescan && i >= key.k_count - 1) { if (macrodef && macrocount <= MAXMACRO) macro[macrocount - 1].m_funct = fp; return (mgwrap(fp, f, n)); } } }
int negative_argument(int f, int n) { KEYMAP *curmap; PF funct; int c; int nn = 0; for (;;) { c = getkey(TRUE); if (c < '0' || c > '9') break; nn *= 10; nn += c - '0'; } if (nn) nn = -nn; else nn = -n; key.k_chars[0] = c; key.k_count = 1; curmap = curbp->b_modes[curbp->b_nmodes]->p_map; while ((funct = doscan(curmap, c, &curmap)) == NULL) { key.k_chars[key.k_count++] = c = getkey(TRUE); } if (macrodef && macrocount < MAXMACRO - 1) { if (f & FFARG) macrocount--; else macro[macrocount - 1].m_funct = universal_argument; macro[macrocount++].m_count = nn; macro[macrocount++].m_funct = funct; } return (mgwrap(funct, FFNEGARG, nn)); }
int universal_argument(int f, int n) { KEYMAP *curmap; PF funct; int c, nn = 4; if (f & FFUNIV) nn *= n; for (;;) { key.k_chars[0] = c = getkey(TRUE); key.k_count = 1; if (c == '-') return (negative_argument(f, nn)); if (c >= '0' && c <= '9') return (digit_argument(f, nn)); curmap = curbp->b_modes[curbp->b_nmodes]->p_map; while ((funct = doscan(curmap, c, &curmap)) == NULL) { key.k_chars[key.k_count++] = c = getkey(TRUE); } if (funct != universal_argument) { if (macrodef && macrocount < MAXMACRO - 1) { if (f & FFARG) macrocount--; macro[macrocount++].m_count = nn; macro[macrocount++].m_funct = funct; } return (mgwrap(funct, FFUNIV, nn)); } nn <<= 2; } }
static int findbind(KEYMAP *map, PF fun, char *buf, size_t len) { KEYMAP *newmap; PF nfun; char buf2[16], keybuf[16]; int c; /* XXX - 256 ? */ for (c = 0; c < 256; c++) { nfun = doscan(map, c, &newmap); if (nfun == fun) { getkeyname(buf, len, c); return (TRUE); } if (nfun == NULL) { if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) { getkeyname(keybuf, sizeof(keybuf), c); (void)snprintf(buf, len, "%s %s", keybuf, buf2); return (TRUE); } } } return (FALSE); }
static int showall(struct buffer *bp, KEYMAP *map, char *prefix) { KEYMAP *newmap; char buf[80], keybuf[16]; PF fun; int c; if (addline(bp, "") == FALSE) return (FALSE); /* XXX - 256 ? */ for (c = 0; c < 256; c++) { fun = doscan(map, c, &newmap); if (fun == rescan || fun == selfinsert) continue; getkeyname(buf, sizeof(buf), c); (void)snprintf(keybuf, sizeof(keybuf), "%s%s ", prefix, buf); if (fun == NULL) { if (showall(bp, newmap, keybuf) == FALSE) return (FALSE); } else { if (addlinef(bp, "%-16s%s", keybuf, function_name(fun)) == FALSE) return (FALSE); } } return (TRUE); }
int doin(void) { KEYMAP *curmap; PF funct; *(promptp = prompt) = '\0'; curmap = curbp->b_modes[curbp->b_nmodes]->p_map; key.k_count = 0; while ((funct = doscan(curmap, (key.k_chars[key.k_count++] = getkey(TRUE)), &curmap)) == NULL) /* nothing */; if (macrodef && macrocount < MAXMACRO) macro[macrocount++].m_funct = funct; return (mgwrap(funct, 0, 1)); }
int help_help(int f, int n) { KEYMAP *kp; PF funct; if ((kp = name_map("help")) == NULL) return (FALSE); ewprintf("a b c: "); do { funct = doscan(kp, getkey(FALSE), NULL); } while (funct == NULL || funct == help_help); if (macrodef && macrocount < MAXMACRO) macro[macrocount - 1].m_funct = funct; return ((*funct)(f, n)); }
int main(int argc, char **argv) { int sts; char *msg; pmResult *irp; /* input pmResult */ pmResult *orp; /* output pmResult */ __pmPDU *pb; /* pdu buffer */ struct timeval unused; unsigned long peek_offset; /* process cmd line args */ if (parseargs(argc, argv) < 0) { pmUsageMessage(&opts); exit(1); } /* input archive name is argv[opts.optind] */ /* output archive name is argv[argc-1]) */ /* output archive */ oname = argv[argc-1]; /* input archive */ iname = argv[opts.optind]; /* * This is the interp mode context */ if ((ictx_a = pmNewContext(PM_CONTEXT_ARCHIVE, iname)) < 0) { fprintf(stderr, "%s: Error: cannot open archive \"%s\" (ctx_a): %s\n", pmProgname, iname, pmErrStr(ictx_a)); exit(1); } if ((sts = pmGetArchiveLabel(&ilabel)) < 0) { fprintf(stderr, "%s: Error: cannot get archive label record (%s): %s\n", pmProgname, iname, pmErrStr(sts)); exit(1); } /* start time */ logstart_tval.tv_sec = ilabel.ll_start.tv_sec; logstart_tval.tv_usec = ilabel.ll_start.tv_usec; /* end time */ if ((sts = pmGetArchiveEnd(&logend_tval)) < 0) { fprintf(stderr, "%s: Error: cannot get end of archive (%s): %s\n", pmProgname, iname, pmErrStr(sts)); exit(1); } if (zarg) { /* use TZ from metrics source (input-archive) */ if ((sts = pmNewZone(ilabel.ll_tz)) < 0) { fprintf(stderr, "%s: Cannot set context timezone: %s\n", pmProgname, pmErrStr(sts)); exit(1); } printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n", ilabel.ll_hostname); } else if (tz != NULL) { /* use TZ as specified by user */ if ((sts = pmNewZone(tz)) < 0) { fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n", pmProgname, tz, pmErrStr(sts)); exit(1); } printf("Note: timezone set to \"TZ=%s\"\n\n", tz); } else { char *tz; tz = __pmTimezone(); /* use TZ from local host */ if ((sts = pmNewZone(tz)) < 0) { fprintf(stderr, "%s: Cannot set local host's timezone: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } /* set winstart and winend timevals */ sts = pmParseTimeWindow(Sarg, Targ, Aarg, Oarg, &logstart_tval, &logend_tval, &winstart_tval, &winend_tval, &unused, &msg); if (sts < 0) { fprintf(stderr, "%s: Invalid time window specified: %s\n", pmProgname, msg); exit(1); } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { char buf[26]; pmCtime((const time_t *)&winstart_tval.tv_sec, buf); fprintf(stderr, "Start time: %s", buf); pmCtime((const time_t *)&winend_tval.tv_sec, buf); fprintf(stderr, "End time: %s", buf); } #endif if ((sts = pmSetMode(PM_MODE_INTERP | PM_XTB_SET(PM_TIME_SEC), &winstart_tval, (int)targ)) < 0) { fprintf(stderr, "%s: pmSetMode(PM_MODE_INTERP ...) failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* create output log - must be done before writing label */ if ((sts = __pmLogCreate("", oname, PM_LOG_VERS02, &logctl)) < 0) { fprintf(stderr, "%s: Error: __pmLogCreate: %s\n", pmProgname, pmErrStr(sts)); exit(1); } /* This must be done after log is created: * - checks that archive version, host, and timezone are ok * - set archive version, host, and timezone of output archive * - set start time * - write labels */ newlabel(); current.tv_sec = logctl.l_label.ill_start.tv_sec = winstart_tval.tv_sec; current.tv_usec = logctl.l_label.ill_start.tv_usec = winstart_tval.tv_usec; /* write label record */ writelabel(); /* * Supress any automatic label creation in libpcp at the first * pmResult write. */ logctl.l_state = PM_LOG_STATE_INIT; /* * Traverse the PMNS to get all the metrics and their metadata */ if ((sts = pmTraversePMNS ("", dometric)) < 0) { fprintf(stderr, "%s: Error traversing namespace ... %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } /* * All the initial metadata has been generated, add timestamp */ fflush(logctl.l_mdfp); __pmLogPutIndex(&logctl, ¤t); written = 0; /* * main loop */ while (sarg == -1 || written < sarg) { /* * do stuff */ if ((sts = pmUseContext(ictx_a)) < 0) { fprintf(stderr, "%s: Error: cannot use context (%s): %s\n", pmProgname, iname, pmErrStr(sts)); goto cleanup; } if ((sts = pmFetch(numpmid, pmidlist, &irp)) < 0) { if (sts == PM_ERR_EOL) break; fprintf(stderr, "%s: Error: pmFetch failed: %s\n", pmProgname, pmErrStr(sts)); exit(1); } if (irp->timestamp.tv_sec > winend_tval.tv_sec || (irp->timestamp.tv_sec == winend_tval.tv_sec && irp->timestamp.tv_usec > winend_tval.tv_usec)) { /* past end time as per -T */ break; } #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) { fprintf(stderr, "input record ...\n"); __pmDumpResult(stderr, irp); } #endif /* * traverse the interval, looking at every archive record ... * we are particularly interested in: * - metric-values that are interpolated but not present in * this interval * - counter wraps * - mark records */ doscan(&irp->timestamp); if ((sts = pmUseContext(ictx_a)) < 0) { fprintf(stderr, "%s: Error: cannot use context (%s): %s\n", pmProgname, iname, pmErrStr(sts)); goto cleanup; } orp = rewrite(irp); #if PCP_DEBUG if (pmDebug & DBG_TRACE_APPL2) { if (orp == NULL) fprintf(stderr, "output record ... none!\n"); else { fprintf(stderr, "output record ...\n"); __pmDumpResult(stderr, orp); } } #endif if (orp == NULL) goto next; /* * convert log record to a PDU, and enforce V2 encoding semantics, * then write it out */ sts = __pmEncodeResult(PDU_OVERRIDE2, orp, &pb); if (sts < 0) { fprintf(stderr, "%s: Error: __pmEncodeResult: %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } /* switch volumes if required */ if (varg > 0) { if (written > 0 && (written % varg) == 0) { __pmTimeval next_stamp; next_stamp.tv_sec = irp->timestamp.tv_sec; next_stamp.tv_usec = irp->timestamp.tv_usec; newvolume(oname, &next_stamp); } } /* * Even without a -v option, we may need to switch volumes * if the data file exceeds 2^31-1 bytes */ peek_offset = ftell(logctl.l_mfp); peek_offset += ((__pmPDUHdr *)pb)->len - sizeof(__pmPDUHdr) + 2*sizeof(int); if (peek_offset > 0x7fffffff) { __pmTimeval next_stamp; next_stamp.tv_sec = irp->timestamp.tv_sec; next_stamp.tv_usec = irp->timestamp.tv_usec; newvolume(oname, &next_stamp); } current.tv_sec = orp->timestamp.tv_sec; current.tv_usec = orp->timestamp.tv_usec; doindom(orp); /* write out log record */ sts = __pmLogPutResult2(&logctl, pb); __pmUnpinPDUBuf(pb); if (sts < 0) { fprintf(stderr, "%s: Error: __pmLogPutResult2: log data: %s\n", pmProgname, pmErrStr(sts)); goto cleanup; } written++; rewrite_free(); next: pmFreeResult(irp); } /* write the last time stamp */ fflush(logctl.l_mfp); fflush(logctl.l_mdfp); __pmLogPutIndex(&logctl, ¤t); exit(exit_status); cleanup: { char fname[MAXNAMELEN]; fprintf(stderr, "Archive \"%s\" not created.\n", oname); snprintf(fname, sizeof(fname), "%s.0", oname); unlink(fname); snprintf(fname, sizeof(fname), "%s.meta", oname); unlink(fname); snprintf(fname, sizeof(fname), "%s.index", oname); unlink(fname); exit(1); } }
/* ARGSUSED */ int desckey(int f, int n) { KEYMAP *curmap; PF funct; int c, m, i, num; char *pep; char dprompt[80]; if (inmacro) return (TRUE); /* ignore inside keyboard macro */ num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt)); if (num >= sizeof(dprompt)) num = sizeof(dprompt) - 1; pep = dprompt + num; key.k_count = 0; m = curbp->b_nmodes; curmap = curbp->b_modes[m]->p_map; for (;;) { for (;;) { ewprintf("%s", dprompt); pep[-1] = ' '; pep = getkeyname(pep, sizeof(dprompt) - (pep - dprompt), key.k_chars[key.k_count++] = c = getkey(FALSE)); if ((funct = doscan(curmap, c, &curmap)) != NULL) break; *pep++ = '-'; *pep = '\0'; } if (funct != rescan) break; if (ISUPPER(key.k_chars[key.k_count - 1])) { funct = doscan(curmap, TOLOWER(key.k_chars[key.k_count - 1]), &curmap); if (funct == NULL) { *pep++ = '-'; *pep = '\0'; continue; } if (funct != rescan) break; } nextmode: if (--m < 0) break; curmap = curbp->b_modes[m]->p_map; for (i = 0; i < key.k_count; i++) { funct = doscan(curmap, key.k_chars[i], &curmap); if (funct != NULL) { if (i == key.k_count - 1 && funct != rescan) goto found; funct = rescan; goto nextmode; } } *pep++ = '-'; *pep = '\0'; } found: if (funct == rescan || funct == selfinsert) ewprintf("%k is not bound to any function"); else if ((pep = (char *)function_name(funct)) != NULL) ewprintf("%k runs the command %s", pep); else ewprintf("%k is bound to an unnamed function"); return (TRUE); }