cmds.c revision 27229
1/*-
2 * Copyright (c) 1980, 1992, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 4/29/95";
36#endif /* not lint */
37
38#include <stdlib.h>
39#include <unistd.h>
40#include <signal.h>
41#include <ctype.h>
42#include <string.h>
43#include "systat.h"
44#include "extern.h"
45
46void
47command(cmd)
48        char *cmd;
49{
50        register struct cmdtab *p;
51        register char *cp;
52	int interval, omask;
53
54	omask = sigblock(sigmask(SIGALRM));
55        for (cp = cmd; *cp && !isspace(*cp); cp++)
56                ;
57        if (*cp)
58                *cp++ = '\0';
59	if (*cmd == '\0')
60		return;
61	for (; *cp && isspace(*cp); cp++)
62		;
63        if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0)
64                die(0);
65	if (strcmp(cmd, "load") == 0) {
66		load();
67		goto done;
68	}
69        if (strcmp(cmd, "stop") == 0) {
70                alarm(0);
71                mvaddstr(CMDLINE, 0, "Refresh disabled.");
72                clrtoeol();
73		goto done;
74        }
75	if (strcmp(cmd, "help") == 0) {
76		int col, len;
77
78		move(CMDLINE, col = 0);
79		for (p = cmdtab; p->c_name; p++) {
80			len = strlen(p->c_name);
81			if (col + len > COLS)
82				break;
83			addstr(p->c_name); col += len;
84			if (col + 1 < COLS)
85				addch(' ');
86		}
87		clrtoeol();
88		goto done;
89	}
90	interval = atoi(cmd);
91        if (interval <= 0 &&
92	    (strcmp(cmd, "start") == 0 || strcmp(cmd, "interval") == 0)) {
93		interval = *cp ? atoi(cp) : naptime;
94                if (interval <= 0) {
95			error("%d: bad interval.", interval);
96			goto done;
97                }
98	}
99	if (interval > 0) {
100                alarm(0);
101                naptime = interval;
102                display(0);
103                status();
104		goto done;
105        }
106	p = lookup(cmd);
107	if (p == (struct cmdtab *)-1) {
108		error("%s: Ambiguous command.", cmd);
109		goto done;
110	}
111        if (p) {
112                if (curcmd == p)
113			goto done;
114                alarm(0);
115		(*curcmd->c_close)(wnd);
116		wnd = (*p->c_open)();
117		if (wnd == 0) {
118			error("Couldn't open new display");
119			wnd = (*curcmd->c_open)();
120			if (wnd == 0) {
121				error("Couldn't change back to previous cmd");
122				exit(1);
123			}
124			p = curcmd;
125		}
126		if ((p->c_flags & CF_INIT) == 0) {
127			if ((*p->c_init)())
128				p->c_flags |= CF_INIT;
129			else
130				goto done;
131		}
132                curcmd = p;
133		labels();
134                display(0);
135                status();
136		goto done;
137        }
138	if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(cmd, cp))
139		error("%s: Unknown command.", cmd);
140done:
141	sigsetmask(omask);
142}
143
144struct cmdtab *
145lookup(name)
146	register char *name;
147{
148	register char *p, *q;
149	register struct cmdtab *c, *found;
150	register int nmatches, longest;
151
152	longest = 0;
153	nmatches = 0;
154	found = (struct cmdtab *) 0;
155	for (c = cmdtab; p = c->c_name; c++) {
156		for (q = name; *q == *p++; q++)
157			if (*q == 0)		/* exact match? */
158				return (c);
159		if (!*q) {			/* the name was a prefix */
160			if (q - name > longest) {
161				longest = q - name;
162				nmatches = 1;
163				found = c;
164			} else if (q - name == longest)
165				nmatches++;
166		}
167	}
168	if (nmatches != 1)
169		return ((struct cmdtab *)-1);
170	return (found);
171}
172
173void
174status()
175{
176
177        error("Showing %s, refresh every %d seconds.",
178          curcmd->c_name, naptime);
179}
180
181int
182prefix(s1, s2)
183        register char *s1, *s2;
184{
185
186        while (*s1 == *s2) {
187                if (*s1 == '\0')
188                        return (1);
189                s1++, s2++;
190        }
191        return (*s1 == '\0');
192}
193