cmds.c revision 27231
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
35#if 0
36static char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 4/29/95";
37#endif
38static const char rcsid[] =
39	"$Id$";
40#endif /* not lint */
41
42#include <stdlib.h>
43#include <unistd.h>
44#include <signal.h>
45#include <ctype.h>
46#include <string.h>
47#include "systat.h"
48#include "extern.h"
49
50void
51command(cmd)
52        char *cmd;
53{
54        register struct cmdtab *p;
55        register char *cp;
56	int interval, omask;
57
58	omask = sigblock(sigmask(SIGALRM));
59        for (cp = cmd; *cp && !isspace(*cp); cp++)
60                ;
61        if (*cp)
62                *cp++ = '\0';
63	if (*cmd == '\0')
64		return;
65	for (; *cp && isspace(*cp); cp++)
66		;
67        if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0)
68                die(0);
69	if (strcmp(cmd, "load") == 0) {
70		load();
71		goto done;
72	}
73        if (strcmp(cmd, "stop") == 0) {
74                alarm(0);
75                mvaddstr(CMDLINE, 0, "Refresh disabled.");
76                clrtoeol();
77		goto done;
78        }
79	if (strcmp(cmd, "help") == 0) {
80		int col, len;
81
82		move(CMDLINE, col = 0);
83		for (p = cmdtab; p->c_name; p++) {
84			len = strlen(p->c_name);
85			if (col + len > COLS)
86				break;
87			addstr(p->c_name); col += len;
88			if (col + 1 < COLS)
89				addch(' ');
90		}
91		clrtoeol();
92		goto done;
93	}
94	interval = atoi(cmd);
95        if (interval <= 0 &&
96	    (strcmp(cmd, "start") == 0 || strcmp(cmd, "interval") == 0)) {
97		interval = *cp ? atoi(cp) : naptime;
98                if (interval <= 0) {
99			error("%d: bad interval.", interval);
100			goto done;
101                }
102	}
103	if (interval > 0) {
104                alarm(0);
105                naptime = interval;
106                display(0);
107                status();
108		goto done;
109        }
110	p = lookup(cmd);
111	if (p == (struct cmdtab *)-1) {
112		error("%s: Ambiguous command.", cmd);
113		goto done;
114	}
115        if (p) {
116                if (curcmd == p)
117			goto done;
118                alarm(0);
119		(*curcmd->c_close)(wnd);
120		wnd = (*p->c_open)();
121		if (wnd == 0) {
122			error("Couldn't open new display");
123			wnd = (*curcmd->c_open)();
124			if (wnd == 0) {
125				error("Couldn't change back to previous cmd");
126				exit(1);
127			}
128			p = curcmd;
129		}
130		if ((p->c_flags & CF_INIT) == 0) {
131			if ((*p->c_init)())
132				p->c_flags |= CF_INIT;
133			else
134				goto done;
135		}
136                curcmd = p;
137		labels();
138                display(0);
139                status();
140		goto done;
141        }
142	if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(cmd, cp))
143		error("%s: Unknown command.", cmd);
144done:
145	sigsetmask(omask);
146}
147
148struct cmdtab *
149lookup(name)
150	register char *name;
151{
152	register char *p, *q;
153	register struct cmdtab *c, *found;
154	register int nmatches, longest;
155
156	longest = 0;
157	nmatches = 0;
158	found = (struct cmdtab *) 0;
159	for (c = cmdtab; p = c->c_name; c++) {
160		for (q = name; *q == *p++; q++)
161			if (*q == 0)		/* exact match? */
162				return (c);
163		if (!*q) {			/* the name was a prefix */
164			if (q - name > longest) {
165				longest = q - name;
166				nmatches = 1;
167				found = c;
168			} else if (q - name == longest)
169				nmatches++;
170		}
171	}
172	if (nmatches > 1)
173		return ((struct cmdtab *)-1);
174	return (found);
175}
176
177void
178status()
179{
180
181        error("Showing %s, refresh every %d seconds.",
182          curcmd->c_name, naptime);
183}
184
185int
186prefix(s1, s2)
187        register char *s1, *s2;
188{
189
190        while (*s1 == *s2) {
191                if (*s1 == '\0')
192                        return (1);
193                s1++, s2++;
194        }
195        return (*s1 == '\0');
196}
197