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