11484d89eSbostic /*-
29d81e80eSbostic * Copyright (c) 1980, 1992, 1993
39d81e80eSbostic * The Regents of the University of California. All rights reserved.
41484d89eSbostic *
51efdcc7dSmckusick * %sccs.include.redist.c%
6c9e4442fSmckusick */
7c9e4442fSmckusick
8b3afe2bbSsam #ifndef lint
9*6cf5fe6fSbostic static char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 04/29/95";
101484d89eSbostic #endif /* not lint */
11b3afe2bbSsam
120241d64aSbostic #include <stdlib.h>
130241d64aSbostic #include <unistd.h>
140241d64aSbostic #include <signal.h>
151c505d7cSmckusick #include <ctype.h>
160241d64aSbostic #include <string.h>
170241d64aSbostic #include "systat.h"
180241d64aSbostic #include "extern.h"
19b3afe2bbSsam
200241d64aSbostic void
command(cmd)21b3afe2bbSsam command(cmd)
22b3afe2bbSsam char *cmd;
23b3afe2bbSsam {
24b3afe2bbSsam register struct cmdtab *p;
250241d64aSbostic register char *cp;
261df1334aSsam int interval, omask;
27b3afe2bbSsam
281df1334aSsam omask = sigblock(sigmask(SIGALRM));
29b3afe2bbSsam for (cp = cmd; *cp && !isspace(*cp); cp++)
30b3afe2bbSsam ;
31b3afe2bbSsam if (*cp)
32b3afe2bbSsam *cp++ = '\0';
33eff1b0bbSsam if (*cmd == '\0')
34eff1b0bbSsam return;
351c505d7cSmckusick for (; *cp && isspace(*cp); cp++)
361c505d7cSmckusick ;
37de2c9d9eSsam if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0)
380241d64aSbostic die(0);
39b3afe2bbSsam if (strcmp(cmd, "load") == 0) {
40b3afe2bbSsam load();
411df1334aSsam goto done;
42b3afe2bbSsam }
43eff1b0bbSsam if (strcmp(cmd, "stop") == 0) {
44eff1b0bbSsam alarm(0);
451c505d7cSmckusick mvaddstr(CMDLINE, 0, "Refresh disabled.");
46eff1b0bbSsam clrtoeol();
471df1334aSsam goto done;
48eff1b0bbSsam }
4908a7e026Ssam if (strcmp(cmd, "help") == 0) {
5008a7e026Ssam int col, len;
51eff1b0bbSsam
5208a7e026Ssam move(CMDLINE, col = 0);
5308a7e026Ssam for (p = cmdtab; p->c_name; p++) {
5408a7e026Ssam len = strlen(p->c_name);
5508a7e026Ssam if (col + len > COLS)
5608a7e026Ssam break;
5708a7e026Ssam addstr(p->c_name); col += len;
5808a7e026Ssam if (col + 1 < COLS)
5908a7e026Ssam addch(' ');
6008a7e026Ssam }
6108a7e026Ssam clrtoeol();
621df1334aSsam goto done;
63eff1b0bbSsam }
6408a7e026Ssam interval = atoi(cmd);
6508a7e026Ssam if (interval <= 0 &&
6608a7e026Ssam (strcmp(cmd, "start") == 0 || strcmp(cmd, "interval") == 0)) {
6708a7e026Ssam interval = *cp ? atoi(cp) : naptime;
6808a7e026Ssam if (interval <= 0) {
6908a7e026Ssam error("%d: bad interval.", interval);
701df1334aSsam goto done;
7108a7e026Ssam }
7208a7e026Ssam }
7308a7e026Ssam if (interval > 0) {
74eff1b0bbSsam alarm(0);
7508a7e026Ssam naptime = interval;
760241d64aSbostic display(0);
77eff1b0bbSsam status();
781df1334aSsam goto done;
79eff1b0bbSsam }
80de2c9d9eSsam p = lookup(cmd);
81eff1b0bbSsam if (p == (struct cmdtab *)-1) {
82eff1b0bbSsam error("%s: Ambiguous command.", cmd);
831df1334aSsam goto done;
84eff1b0bbSsam }
85eff1b0bbSsam if (p) {
86b3afe2bbSsam if (curcmd == p)
871df1334aSsam goto done;
88b3afe2bbSsam alarm(0);
89b3afe2bbSsam (*curcmd->c_close)(wnd);
90b3afe2bbSsam wnd = (*p->c_open)();
9188c39ecaSsam if (wnd == 0) {
9288c39ecaSsam error("Couldn't open new display");
9388c39ecaSsam wnd = (*curcmd->c_open)();
9488c39ecaSsam if (wnd == 0) {
9588c39ecaSsam error("Couldn't change back to previous cmd");
9688c39ecaSsam exit(1);
9788c39ecaSsam }
9888c39ecaSsam p = curcmd;
9988c39ecaSsam }
10008a7e026Ssam if ((p->c_flags & CF_INIT) == 0) {
101b92b7775Sbloom if ((*p->c_init)())
10208a7e026Ssam p->c_flags |= CF_INIT;
103b92b7775Sbloom else
104b92b7775Sbloom goto done;
105b3afe2bbSsam }
106b92b7775Sbloom curcmd = p;
107b3afe2bbSsam labels();
1080241d64aSbostic display(0);
109b3afe2bbSsam status();
1101df1334aSsam goto done;
111b3afe2bbSsam }
1121df1334aSsam if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(cmd, cp))
1131c505d7cSmckusick error("%s: Unknown command.", cmd);
1141df1334aSsam done:
1151df1334aSsam sigsetmask(omask);
116b3afe2bbSsam }
117b3afe2bbSsam
118b3afe2bbSsam struct cmdtab *
lookup(name)119de2c9d9eSsam lookup(name)
120b3afe2bbSsam register char *name;
121b3afe2bbSsam {
122b3afe2bbSsam register char *p, *q;
123b3afe2bbSsam register struct cmdtab *c, *found;
124b3afe2bbSsam register int nmatches, longest;
125b3afe2bbSsam
126b3afe2bbSsam longest = 0;
127b3afe2bbSsam nmatches = 0;
1283c6f0a97Stef found = (struct cmdtab *) 0;
129b3afe2bbSsam for (c = cmdtab; p = c->c_name; c++) {
130b3afe2bbSsam for (q = name; *q == *p++; q++)
131b3afe2bbSsam if (*q == 0) /* exact match? */
132b3afe2bbSsam return (c);
133b3afe2bbSsam if (!*q) { /* the name was a prefix */
134b3afe2bbSsam if (q - name > longest) {
135b3afe2bbSsam longest = q - name;
136b3afe2bbSsam nmatches = 1;
137b3afe2bbSsam found = c;
138b3afe2bbSsam } else if (q - name == longest)
139b3afe2bbSsam nmatches++;
140b3afe2bbSsam }
141b3afe2bbSsam }
142*6cf5fe6fSbostic if (nmatches != 1)
143b3afe2bbSsam return ((struct cmdtab *)-1);
144b3afe2bbSsam return (found);
145b3afe2bbSsam }
146b3afe2bbSsam
1470241d64aSbostic void
status()148b3afe2bbSsam status()
149b3afe2bbSsam {
150b3afe2bbSsam
1511c505d7cSmckusick error("Showing %s, refresh every %d seconds.",
152b3afe2bbSsam curcmd->c_name, naptime);
153b3afe2bbSsam }
154b3afe2bbSsam
1550241d64aSbostic int
prefix(s1,s2)1561df1334aSsam prefix(s1, s2)
1571df1334aSsam register char *s1, *s2;
1581df1334aSsam {
1591df1334aSsam
1601df1334aSsam while (*s1 == *s2) {
1611df1334aSsam if (*s1 == '\0')
1621df1334aSsam return (1);
1631df1334aSsam s1++, s2++;
1641df1334aSsam }
1651df1334aSsam return (*s1 == '\0');
1661df1334aSsam }
167