cmds.c revision 108683
1139826Simp/*-
253541Sshin * Copyright (c) 1980, 1992, 1993
353541Sshin *	The Regents of the University of California.  All rights reserved.
453541Sshin *
553541Sshin * Redistribution and use in source and binary forms, with or without
653541Sshin * modification, are permitted provided that the following conditions
753541Sshin * are met:
853541Sshin * 1. Redistributions of source code must retain the above copyright
953541Sshin *    notice, this list of conditions and the following disclaimer.
1053541Sshin * 2. Redistributions in binary form must reproduce the above copyright
1153541Sshin *    notice, this list of conditions and the following disclaimer in the
1253541Sshin *    documentation and/or other materials provided with the distribution.
1353541Sshin * 3. All advertising materials mentioning features or use of this software
1453541Sshin *    must display the following acknowledgement:
1553541Sshin *	This product includes software developed by the University of
1653541Sshin *	California, Berkeley and its contributors.
1753541Sshin * 4. Neither the name of the University nor the names of its contributors
1853541Sshin *    may be used to endorse or promote products derived from this software
1953541Sshin *    without specific prior written permission.
2053541Sshin *
2153541Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2253541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2353541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2453541Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2553541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2653541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2753541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28174510Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29174510Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3053541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3153541Sshin * SUCH DAMAGE.
32139826Simp */
3353541Sshin
3453541Sshin#include <sys/cdefs.h>
3553541Sshin
3653541Sshin__FBSDID("$FreeBSD: head/usr.bin/systat/cmds.c 108683 2003-01-04 21:58:25Z phk $");
3753541Sshin
3853541Sshin#ifdef lint
3953541Sshinstatic const char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 4/29/95";
4053541Sshin#endif
4153541Sshin
4253541Sshin#include <ctype.h>
4353541Sshin#include <signal.h>
4453541Sshin#include <stdlib.h>
4553541Sshin#include <string.h>
4653541Sshin#include <unistd.h>
4753541Sshin
4853541Sshin#include "systat.h"
4953541Sshin#include "extern.h"
5053541Sshin
5153541Sshinvoid
5253541Sshincommand(cmd)
5353541Sshin        const char *cmd;
5453541Sshin{
5553541Sshin        struct cmdtab *p;
5653541Sshin        char *cp, *tmpstr, *tmpstr1;
5753541Sshin	int interval, omask;
5853541Sshin
5953541Sshin	tmpstr = tmpstr1 = strdup(cmd);
6053541Sshin	omask = sigblock(sigmask(SIGALRM));
6153541Sshin        for (cp = tmpstr1; *cp && !isspace(*cp); cp++)
62174510Sobrien                ;
63174510Sobrien        if (*cp)
64174510Sobrien                *cp++ = '\0';
6553541Sshin	if (*tmpstr1 == '\0')
6653541Sshin		return;
6753541Sshin	for (; *cp && isspace(*cp); cp++)
68185751Simp		;
6953541Sshin        if (strcmp(tmpstr1, "quit") == 0 || strcmp(tmpstr1, "q") == 0)
7053541Sshin                die(0);
7153541Sshin	if (strcmp(tmpstr1, "load") == 0) {
7253541Sshin		load();
7353541Sshin		goto done;
74185747Skmacy	}
7553541Sshin        if (strcmp(tmpstr1, "stop") == 0) {
76120727Ssam                alarm(0);
7753541Sshin                mvaddstr(CMDLINE, 0, "Refresh disabled.");
7853541Sshin                clrtoeol();
79257176Sglebius		goto done;
80194714Sbz        }
81185571Sbz	if (strcmp(tmpstr1, "help") == 0) {
8253541Sshin		int _col, _len;
8353541Sshin
8453541Sshin		move(CMDLINE, _col = 0);
8553541Sshin		for (p = cmdtab; p->c_name; p++) {
8662587Sitojun			_len = strlen(p->c_name);
8753541Sshin			if (_col + _len > COLS)
8853541Sshin				break;
8962587Sitojun			addstr(p->c_name); _col += _len;
90121283Sume			if (_col + 1 < COLS)
9153541Sshin				addch(' ');
9253541Sshin		}
9353541Sshin		clrtoeol();
9453541Sshin		goto done;
9553541Sshin	}
9653541Sshin	interval = atoi(tmpstr1);
97175162Sobrien        if (interval <= 0 &&
98193731Szec	    (strcmp(tmpstr1, "start") == 0 || strcmp(tmpstr1, "interval") == 0)) {
99193731Szec		interval = *cp ? atoi(cp) : naptime;
100193731Szec                if (interval <= 0) {
10153541Sshin			error("%d: bad interval.", interval);
10253541Sshin			goto done;
10353541Sshin                }
10453541Sshin	}
10553541Sshin	if (interval > 0) {
10653541Sshin                alarm(0);
107171260Sdelphij                naptime = interval;
10853541Sshin                display(0);
10953541Sshin                status();
11053541Sshin		goto done;
11153541Sshin        }
11253541Sshin	p = lookup(tmpstr1);
113186119Sqingli	if (p == (struct cmdtab *)-1) {
11453541Sshin		error("%s: Ambiguous command.", tmpstr1);
11553541Sshin		goto done;
11653541Sshin	}
11753541Sshin        if (p) {
11853541Sshin                if (curcmd == p)
11953541Sshin			goto done;
12053541Sshin                alarm(0);
12153541Sshin		(*curcmd->c_close)(wnd);
12253541Sshin		curcmd->c_flags &= ~CF_INIT;
12353541Sshin		wnd = (*p->c_open)();
12453541Sshin		if (wnd == 0) {
12553541Sshin			error("Couldn't open new display");
12653541Sshin			wnd = (*curcmd->c_open)();
12753541Sshin			if (wnd == 0) {
12853541Sshin				error("Couldn't change back to previous cmd");
12953541Sshin				exit(1);
13053541Sshin			}
13153541Sshin			p = curcmd;
13253541Sshin		}
13353541Sshin		if ((p->c_flags & CF_INIT) == 0) {
13453541Sshin			if ((*p->c_init)())
13553541Sshin				p->c_flags |= CF_INIT;
13653541Sshin			else
13753541Sshin				goto done;
13853541Sshin		}
139262763Sglebius                curcmd = p;
140262763Sglebius		labels();
14153541Sshin                display(0);
14253541Sshin                status();
143186119Sqingli		goto done;
14453541Sshin        }
14553541Sshin	if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(tmpstr1, cp))
14653541Sshin		error("%s: Unknown command.", tmpstr1);
14753541Sshindone:
14853541Sshin	sigsetmask(omask);
14953541Sshin	free(tmpstr);
15053541Sshin}
15153541Sshin
15253541Sshinstruct cmdtab *
15353541Sshinlookup(name)
15453541Sshin	const char *name;
15553541Sshin{
15653541Sshin	const char *p, *q;
157231852Sbz	struct cmdtab *ct, *found;
158231852Sbz	int nmatches, longest;
15953541Sshin
160186119Sqingli	longest = 0;
16153541Sshin	nmatches = 0;
16253541Sshin	found = (struct cmdtab *) 0;
16353541Sshin	for (ct = cmdtab; (p = ct->c_name); ct++) {
16453541Sshin		for (q = name; *q == *p++; q++)
16553541Sshin			if (*q == 0)		/* exact match? */
166120727Ssam				return (ct);
16753541Sshin		if (!*q) {			/* the name was a prefix */
16853541Sshin			if (q - name > longest) {
169186119Sqingli				longest = q - name;
17053541Sshin				nmatches = 1;
17153541Sshin				found = ct;
17262604Sitojun			} else if (q - name == longest)
17362604Sitojun				nmatches++;
174215701Sdim		}
175207369Sbz	}
176207369Sbz	if (nmatches > 1)
177195699Srwatson		return ((struct cmdtab *)-1);
178195699Srwatson	return (found);
179120913Sume}
18053541Sshin
18153541Sshinvoid
18253541Sshinstatus()
18353541Sshin{
18453541Sshin
18553541Sshin        error("Showing %s, refresh every %d seconds.",
18653541Sshin          curcmd->c_name, naptime);
18753541Sshin}
18853541Sshin
18953541Sshinint
19053541Sshinprefix(s1, s2)
19153541Sshin        const char *s1, *s2;
19253541Sshin{
19353541Sshin
19453541Sshin        while (*s1 == *s2) {
19553541Sshin                if (*s1 == '\0')
19653541Sshin                        return (1);
197215701Sdim                s1++, s2++;
198195727Srwatson        }
199195699Srwatson        return (*s1 == '\0');
20053541Sshin}
20153541Sshin