11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1980, 1992, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 4. Neither the name of the University nor the names of its contributors
141590Srgrimes *    may be used to endorse or promote products derived from this software
151590Srgrimes *    without specific prior written permission.
161590Srgrimes *
171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271590Srgrimes * SUCH DAMAGE.
281590Srgrimes */
291590Srgrimes
3087715Smarkm#include <sys/cdefs.h>
3187715Smarkm
3287715Smarkm__FBSDID("$FreeBSD: stable/11/usr.bin/systat/cmds.c 336119 2018-07-09 05:56:13Z delphij $");
3387715Smarkm
3487715Smarkm#ifdef lint
3587715Smarkmstatic const char sccsid[] = "@(#)cmds.c	8.2 (Berkeley) 4/29/95";
3627231Sbde#endif
371590Srgrimes
38240605Smelifaro#include <sys/param.h>
39240605Smelifaro
4087715Smarkm#include <ctype.h>
4187715Smarkm#include <signal.h>
421590Srgrimes#include <stdlib.h>
4387715Smarkm#include <string.h>
441590Srgrimes#include <unistd.h>
4587715Smarkm
461590Srgrimes#include "systat.h"
471590Srgrimes#include "extern.h"
481590Srgrimes
491590Srgrimesvoid
50175387Sdelphijcommand(const char *cmd)
511590Srgrimes{
52226396Sed	struct cmdtab *p;
53226396Sed	char *cp, *tmpstr, *tmpstr1;
54240605Smelifaro	double t;
551590Srgrimes
5687715Smarkm	tmpstr = tmpstr1 = strdup(cmd);
57226396Sed	for (cp = tmpstr1; *cp && !isspace(*cp); cp++)
58226396Sed		;
59226396Sed	if (*cp)
60226396Sed		*cp++ = '\0';
6187715Smarkm	if (*tmpstr1 == '\0')
62336119Sdelphij		goto done;
631590Srgrimes	for (; *cp && isspace(*cp); cp++)
641590Srgrimes		;
65226396Sed	if (strcmp(tmpstr1, "quit") == 0 || strcmp(tmpstr1, "q") == 0)
66226396Sed		die(0);
6787715Smarkm	if (strcmp(tmpstr1, "load") == 0) {
681590Srgrimes		load();
691590Srgrimes		goto done;
701590Srgrimes	}
71226396Sed	if (strcmp(tmpstr1, "stop") == 0) {
72240605Smelifaro		delay = 0;
73226396Sed		mvaddstr(CMDLINE, 0, "Refresh disabled.");
74226396Sed		clrtoeol();
751590Srgrimes		goto done;
76226396Sed	}
7787715Smarkm	if (strcmp(tmpstr1, "help") == 0) {
7887715Smarkm		int _col, _len;
791590Srgrimes
8087715Smarkm		move(CMDLINE, _col = 0);
811590Srgrimes		for (p = cmdtab; p->c_name; p++) {
8287715Smarkm			_len = strlen(p->c_name);
8387715Smarkm			if (_col + _len > COLS)
841590Srgrimes				break;
8587715Smarkm			addstr(p->c_name); _col += _len;
8687715Smarkm			if (_col + 1 < COLS)
871590Srgrimes				addch(' ');
881590Srgrimes		}
891590Srgrimes		clrtoeol();
901590Srgrimes		goto done;
911590Srgrimes	}
92240605Smelifaro	t = strtod(tmpstr1, NULL) * 1000000.0;
93240605Smelifaro	if (t > 0 && t < (double)UINT_MAX)
94240605Smelifaro		delay = (unsigned int)t;
95240605Smelifaro	if ((t <= 0 || t > (double)UINT_MAX) &&
96240605Smelifaro	    (strcmp(tmpstr1, "start") == 0 ||
97240605Smelifaro	    strcmp(tmpstr1, "interval") == 0)) {
98240605Smelifaro		if (*cp != '\0') {
99240605Smelifaro			t = strtod(cp, NULL) * 1000000.0;
100240605Smelifaro			if (t <= 0 || t >= (double)UINT_MAX) {
101240605Smelifaro				error("%d: bad interval.", (int)t);
102240605Smelifaro				goto done;
103240605Smelifaro			}
104226396Sed		}
1051590Srgrimes	}
106240605Smelifaro	if (t > 0) {
107240605Smelifaro		delay = (unsigned int)t;
108240605Smelifaro		display();
109226396Sed		status();
1101590Srgrimes		goto done;
111226396Sed	}
11287715Smarkm	p = lookup(tmpstr1);
1131590Srgrimes	if (p == (struct cmdtab *)-1) {
11487715Smarkm		error("%s: Ambiguous command.", tmpstr1);
1151590Srgrimes		goto done;
1161590Srgrimes	}
117226396Sed	if (p) {
118226396Sed		if (curcmd == p)
1191590Srgrimes			goto done;
1201590Srgrimes		(*curcmd->c_close)(wnd);
121108683Sphk		curcmd->c_flags &= ~CF_INIT;
1221590Srgrimes		wnd = (*p->c_open)();
123298324Saraujo		if (wnd == NULL) {
1241590Srgrimes			error("Couldn't open new display");
1251590Srgrimes			wnd = (*curcmd->c_open)();
126298324Saraujo			if (wnd == NULL) {
1271590Srgrimes				error("Couldn't change back to previous cmd");
1281590Srgrimes				exit(1);
1291590Srgrimes			}
1301590Srgrimes			p = curcmd;
1311590Srgrimes		}
1321590Srgrimes		if ((p->c_flags & CF_INIT) == 0) {
1331590Srgrimes			if ((*p->c_init)())
1341590Srgrimes				p->c_flags |= CF_INIT;
1351590Srgrimes			else
1361590Srgrimes				goto done;
1371590Srgrimes		}
138226396Sed		curcmd = p;
1391590Srgrimes		labels();
140240605Smelifaro		display();
141226396Sed		status();
1421590Srgrimes		goto done;
143226396Sed	}
144298324Saraujo	if (curcmd->c_cmd == NULL || !(*curcmd->c_cmd)(tmpstr1, cp))
14587715Smarkm		error("%s: Unknown command.", tmpstr1);
1461590Srgrimesdone:
14787715Smarkm	free(tmpstr);
1481590Srgrimes}
1491590Srgrimes
1501590Srgrimesstruct cmdtab *
151175387Sdelphijlookup(const char *name)
1521590Srgrimes{
15387715Smarkm	const char *p, *q;
15487715Smarkm	struct cmdtab *ct, *found;
15587715Smarkm	int nmatches, longest;
1561590Srgrimes
1571590Srgrimes	longest = 0;
1581590Srgrimes	nmatches = 0;
1591590Srgrimes	found = (struct cmdtab *) 0;
16087715Smarkm	for (ct = cmdtab; (p = ct->c_name); ct++) {
1611590Srgrimes		for (q = name; *q == *p++; q++)
1621590Srgrimes			if (*q == 0)		/* exact match? */
16387715Smarkm				return (ct);
1641590Srgrimes		if (!*q) {			/* the name was a prefix */
1651590Srgrimes			if (q - name > longest) {
1661590Srgrimes				longest = q - name;
1671590Srgrimes				nmatches = 1;
16887715Smarkm				found = ct;
1691590Srgrimes			} else if (q - name == longest)
1701590Srgrimes				nmatches++;
1711590Srgrimes		}
1721590Srgrimes	}
17327231Sbde	if (nmatches > 1)
1741590Srgrimes		return ((struct cmdtab *)-1);
1751590Srgrimes	return (found);
1761590Srgrimes}
1771590Srgrimes
1781590Srgrimesvoid
179175387Sdelphijstatus(void)
1801590Srgrimes{
1811590Srgrimes
182226396Sed	error("Showing %s, refresh every %d seconds.",
183240605Smelifaro	  curcmd->c_name, delay / 1000000);
1841590Srgrimes}
1851590Srgrimes
1861590Srgrimesint
187175387Sdelphijprefix(const char *s1, const char *s2)
1881590Srgrimes{
1891590Srgrimes
190226396Sed	while (*s1 == *s2) {
191226396Sed		if (*s1 == '\0')
192226396Sed			return (1);
193226396Sed		s1++, s2++;
194226396Sed	}
195226396Sed	return (*s1 == '\0');
1961590Srgrimes}
197