cmds.c revision 231279
159769Sgrog/*-
259769Sgrog * Copyright (c) 1980, 1992, 1993
324424Swosch *	The Regents of the University of California.  All rights reserved.
424424Swosch *
524424Swosch * Redistribution and use in source and binary forms, with or without
624424Swosch * modification, are permitted provided that the following conditions
724424Swosch * are met:
824424Swosch * 1. Redistributions of source code must retain the above copyright
924424Swosch *    notice, this list of conditions and the following disclaimer.
1024424Swosch * 2. Redistributions in binary form must reproduce the above copyright
1124424Swosch *    notice, this list of conditions and the following disclaimer in the
1224424Swosch *    documentation and/or other materials provided with the distribution.
1324424Swosch * 4. Neither the name of the University nor the names of its contributors
1424424Swosch *    may be used to endorse or promote products derived from this software
1542704Swosch *    without specific prior written permission.
1642704Swosch *
1742704Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1824424Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1942704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2042704Swosch * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2142704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2242704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2342704Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2442704Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2542704Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2642704Swosch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2742704Swosch * SUCH DAMAGE.
2842704Swosch */
2942704Swosch
3059769Sgrog#include <sys/cdefs.h>
3159769Sgrog
3259769Sgrog__FBSDID("$FreeBSD: stable/9/usr.bin/systat/cmds.c 231279 2012-02-09 15:21:54Z ed $");
3359769Sgrog
3459769Sgrog#ifdef lint
3559769Sgrogstatic const char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 4/29/95";
3659769Sgrog#endif
3759769Sgrog
3859769Sgrog#include <ctype.h>
3924424Swosch#include <signal.h>
4042704Swosch#include <stdlib.h>
4124424Swosch#include <string.h>
4242704Swosch#include <unistd.h>
4324424Swosch
4442704Swosch#include "systat.h"
4524424Swosch#include "extern.h"
4624424Swosch
4724424Swoschvoid
4842704Swoschcommand(const char *cmd)
4925031Swosch{
5059156Swosch	struct cmdtab *p;
5125031Swosch	char *cp, *tmpstr, *tmpstr1;
5225031Swosch	int interval, omask;
5324424Swosch
5424424Swosch	tmpstr = tmpstr1 = strdup(cmd);
5524424Swosch	omask = sigblock(sigmask(SIGALRM));
5624424Swosch	for (cp = tmpstr1; *cp && !isspace(*cp); cp++)
5771231Sitojun		;
5824424Swosch	if (*cp)
5971231Sitojun		*cp++ = '\0';
6025031Swosch	if (*tmpstr1 == '\0')
6171231Sitojun		return;
6224424Swosch	for (; *cp && isspace(*cp); cp++)
6325031Swosch		;
6425031Swosch	if (strcmp(tmpstr1, "quit") == 0 || strcmp(tmpstr1, "q") == 0)
6571231Sitojun		die(0);
6625031Swosch	if (strcmp(tmpstr1, "load") == 0) {
6771231Sitojun		load();
6870110Swosch		goto done;
6970110Swosch	}
7070110Swosch	if (strcmp(tmpstr1, "stop") == 0) {
7170110Swosch		alarm(0);
7270110Swosch		mvaddstr(CMDLINE, 0, "Refresh disabled.");
7370110Swosch		clrtoeol();
7470110Swosch		goto done;
7570110Swosch	}
7670110Swosch	if (strcmp(tmpstr1, "help") == 0) {
7770110Swosch		int _col, _len;
7870110Swosch
7980675Sasmodai		move(CMDLINE, _col = 0);
8080675Sasmodai		for (p = cmdtab; p->c_name; p++) {
8180675Sasmodai			_len = strlen(p->c_name);
8280675Sasmodai			if (_col + _len > COLS)
8380675Sasmodai				break;
8480675Sasmodai			addstr(p->c_name); _col += _len;
8580675Sasmodai			if (_col + 1 < COLS)
8680675Sasmodai				addch(' ');
8780675Sasmodai		}
8880675Sasmodai		clrtoeol();
8980675Sasmodai		goto done;
9080675Sasmodai	}
9180675Sasmodai	interval = atoi(tmpstr1);
9280675Sasmodai	if (interval <= 0 &&
9380675Sasmodai	    (strcmp(tmpstr1, "start") == 0 || strcmp(tmpstr1, "interval") == 0)) {
9480675Sasmodai		interval = *cp ? atoi(cp) : naptime;
9580675Sasmodai		if (interval <= 0) {
9680675Sasmodai			error("%d: bad interval.", interval);
9780675Sasmodai			goto done;
9880675Sasmodai		}
9980675Sasmodai	}
10080675Sasmodai	if (interval > 0) {
10180675Sasmodai		alarm(0);
10280675Sasmodai		naptime = interval;
10380675Sasmodai		display(0);
10480675Sasmodai		status();
10580675Sasmodai		goto done;
10680675Sasmodai	}
10780675Sasmodai	p = lookup(tmpstr1);
10880675Sasmodai	if (p == (struct cmdtab *)-1) {
10980675Sasmodai		error("%s: Ambiguous command.", tmpstr1);
11080675Sasmodai		goto done;
11180675Sasmodai	}
11280675Sasmodai	if (p) {
11380675Sasmodai		if (curcmd == p)
11480675Sasmodai			goto done;
11580675Sasmodai		alarm(0);
11680675Sasmodai		(*curcmd->c_close)(wnd);
11780675Sasmodai		curcmd->c_flags &= ~CF_INIT;
11880675Sasmodai		wnd = (*p->c_open)();
11980675Sasmodai		if (wnd == 0) {
12080675Sasmodai			error("Couldn't open new display");
12180675Sasmodai			wnd = (*curcmd->c_open)();
12280675Sasmodai			if (wnd == 0) {
12380675Sasmodai				error("Couldn't change back to previous cmd");
12480675Sasmodai				exit(1);
12580675Sasmodai			}
12680675Sasmodai			p = curcmd;
12780675Sasmodai		}
12880675Sasmodai		if ((p->c_flags & CF_INIT) == 0) {
12980675Sasmodai			if ((*p->c_init)())
13080675Sasmodai				p->c_flags |= CF_INIT;
13180675Sasmodai			else
13280675Sasmodai				goto done;
13380675Sasmodai		}
13480675Sasmodai		curcmd = p;
13580675Sasmodai		labels();
13680675Sasmodai		display(0);
13780675Sasmodai		status();
138101401Swosch		goto done;
13980675Sasmodai	}
14087200Swosch	if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(tmpstr1, cp))
14187200Swosch		error("%s: Unknown command.", tmpstr1);
14287200Swoschdone:
14380675Sasmodai	sigsetmask(omask);
144104772Smaxim	free(tmpstr);
145104772Smaxim}
146104772Smaxim
147104772Smaximstruct cmdtab *
148104781Sjhblookup(const char *name)
149104781Sjhb{
150104781Sjhb	const char *p, *q;
151104781Sjhb	struct cmdtab *ct, *found;
152104781Sjhb	int nmatches, longest;
153104781Sjhb
154104781Sjhb	longest = 0;
155104781Sjhb	nmatches = 0;
156104781Sjhb	found = (struct cmdtab *) 0;
157104781Sjhb	for (ct = cmdtab; (p = ct->c_name); ct++) {
158104781Sjhb		for (q = name; *q == *p++; q++)
159104781Sjhb			if (*q == 0)		/* exact match? */
160104781Sjhb				return (ct);
161104781Sjhb		if (!*q) {			/* the name was a prefix */
16280675Sasmodai			if (q - name > longest) {
16380675Sasmodai				longest = q - name;
16480675Sasmodai				nmatches = 1;
165104781Sjhb				found = ct;
16624424Swosch			} else if (q - name == longest)
16724424Swosch				nmatches++;
16824424Swosch		}
16924424Swosch	}
17069277Sasmodai	if (nmatches > 1)
17169277Sasmodai		return ((struct cmdtab *)-1);
17224424Swosch	return (found);
17325031Swosch}
17425031Swosch
17525031Swoschvoid
17680675Sasmodaistatus(void)
177104782Sjhb{
17825031Swosch
179104782Sjhb	error("Showing %s, refresh every %d seconds.",
180104782Sjhb	  curcmd->c_name, naptime);
181104782Sjhb}
18225031Swosch
18325031Swoschint
18425031Swoschprefix(const char *s1, const char *s2)
18525031Swosch{
18625031Swosch
18745349Swosch	while (*s1 == *s2) {
18845349Swosch		if (*s1 == '\0')
189104782Sjhb			return (1);
190104782Sjhb		s1++, s2++;
191104782Sjhb	}
192104782Sjhb	return (*s1 == '\0');
19342704Swosch}
19425031Swosch