| 1 | /* |
| 2 | * Copyright (c) 1980 Regents of the University of California. |
| 3 | * All rights reserved. The Berkeley software License Agreement |
| 4 | * specifies the terms and conditions for redistribution. |
| 5 | */ |
| 6 | |
| 7 | #ifndef lint |
| 8 | static char sccsid[] = "@(#)cmds.c 5.7 (Berkeley) %G%"; |
| 9 | #endif not lint |
| 10 | |
| 11 | /* |
| 12 | * Command support. |
| 13 | */ |
| 14 | |
| 15 | #include "systat.h" |
| 16 | #include <ctype.h> |
| 17 | |
| 18 | command(cmd) |
| 19 | char *cmd; |
| 20 | { |
| 21 | register char *cp; |
| 22 | register struct cmdtab *p; |
| 23 | int interval, omask; |
| 24 | |
| 25 | omask = sigblock(sigmask(SIGALRM)); |
| 26 | for (cp = cmd; *cp && !isspace(*cp); cp++) |
| 27 | ; |
| 28 | if (*cp) |
| 29 | *cp++ = '\0'; |
| 30 | if (*cmd == '\0') |
| 31 | return; |
| 32 | for (; *cp && isspace(*cp); cp++) |
| 33 | ; |
| 34 | if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0) |
| 35 | die(); |
| 36 | if (strcmp(cmd, "load") == 0) { |
| 37 | load(); |
| 38 | goto done; |
| 39 | } |
| 40 | if (strcmp(cmd, "stop") == 0) { |
| 41 | alarm(0); |
| 42 | mvaddstr(CMDLINE, 0, "Refresh disabled."); |
| 43 | clrtoeol(); |
| 44 | goto done; |
| 45 | } |
| 46 | if (strcmp(cmd, "help") == 0) { |
| 47 | int col, len; |
| 48 | |
| 49 | move(CMDLINE, col = 0); |
| 50 | for (p = cmdtab; p->c_name; p++) { |
| 51 | len = strlen(p->c_name); |
| 52 | if (col + len > COLS) |
| 53 | break; |
| 54 | addstr(p->c_name); col += len; |
| 55 | if (col + 1 < COLS) |
| 56 | addch(' '); |
| 57 | } |
| 58 | clrtoeol(); |
| 59 | goto done; |
| 60 | } |
| 61 | interval = atoi(cmd); |
| 62 | if (interval <= 0 && |
| 63 | (strcmp(cmd, "start") == 0 || strcmp(cmd, "interval") == 0)) { |
| 64 | interval = *cp ? atoi(cp) : naptime; |
| 65 | if (interval <= 0) { |
| 66 | error("%d: bad interval.", interval); |
| 67 | goto done; |
| 68 | } |
| 69 | } |
| 70 | if (interval > 0) { |
| 71 | alarm(0); |
| 72 | naptime = interval; |
| 73 | display(); |
| 74 | status(); |
| 75 | goto done; |
| 76 | } |
| 77 | p = lookup(cmd); |
| 78 | if (p == (struct cmdtab *)-1) { |
| 79 | error("%s: Ambiguous command.", cmd); |
| 80 | goto done; |
| 81 | } |
| 82 | if (p) { |
| 83 | if (curcmd == p) |
| 84 | goto done; |
| 85 | alarm(0); |
| 86 | (*curcmd->c_close)(wnd); |
| 87 | wnd = (*p->c_open)(); |
| 88 | if (wnd == 0) { |
| 89 | error("Couldn't open new display"); |
| 90 | wnd = (*curcmd->c_open)(); |
| 91 | if (wnd == 0) { |
| 92 | error("Couldn't change back to previous cmd"); |
| 93 | exit(1); |
| 94 | } |
| 95 | p = curcmd; |
| 96 | } |
| 97 | if ((p->c_flags & CF_INIT) == 0) { |
| 98 | if ((*p->c_init)()) |
| 99 | p->c_flags |= CF_INIT; |
| 100 | else |
| 101 | goto done; |
| 102 | } |
| 103 | curcmd = p; |
| 104 | labels(); |
| 105 | display(); |
| 106 | status(); |
| 107 | goto done; |
| 108 | } |
| 109 | if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(cmd, cp)) |
| 110 | error("%s: Unknown command.", cmd); |
| 111 | done: |
| 112 | sigsetmask(omask); |
| 113 | } |
| 114 | |
| 115 | struct cmdtab * |
| 116 | lookup(name) |
| 117 | register char *name; |
| 118 | { |
| 119 | register char *p, *q; |
| 120 | register struct cmdtab *c, *found; |
| 121 | register int nmatches, longest; |
| 122 | |
| 123 | longest = 0; |
| 124 | nmatches = 0; |
| 125 | found = (struct cmdtab *) 0; |
| 126 | for (c = cmdtab; p = c->c_name; c++) { |
| 127 | for (q = name; *q == *p++; q++) |
| 128 | if (*q == 0) /* exact match? */ |
| 129 | return (c); |
| 130 | if (!*q) { /* the name was a prefix */ |
| 131 | if (q - name > longest) { |
| 132 | longest = q - name; |
| 133 | nmatches = 1; |
| 134 | found = c; |
| 135 | } else if (q - name == longest) |
| 136 | nmatches++; |
| 137 | } |
| 138 | } |
| 139 | if (nmatches > 1) |
| 140 | return ((struct cmdtab *)-1); |
| 141 | return (found); |
| 142 | } |
| 143 | |
| 144 | status() |
| 145 | { |
| 146 | |
| 147 | error("Showing %s, refresh every %d seconds.", |
| 148 | curcmd->c_name, naptime); |
| 149 | } |
| 150 | |
| 151 | suspend() |
| 152 | { |
| 153 | int oldmask; |
| 154 | extern sig_t sigtstpdfl; |
| 155 | |
| 156 | alarm(0); |
| 157 | move(CMDLINE, 0); |
| 158 | refresh(); |
| 159 | echo(); |
| 160 | nocrmode(); |
| 161 | signal(SIGTSTP, sigtstpdfl); |
| 162 | oldmask = sigsetmask(0); |
| 163 | kill(getpid(), SIGTSTP); |
| 164 | sigsetmask(oldmask); |
| 165 | signal(SIGTSTP, suspend); |
| 166 | crmode(); |
| 167 | noecho(); |
| 168 | move(CMDLINE, col); |
| 169 | alarm(naptime); |
| 170 | } |
| 171 | |
| 172 | prefix(s1, s2) |
| 173 | register char *s1, *s2; |
| 174 | { |
| 175 | |
| 176 | while (*s1 == *s2) { |
| 177 | if (*s1 == '\0') |
| 178 | return (1); |
| 179 | s1++, s2++; |
| 180 | } |
| 181 | return (*s1 == '\0'); |
| 182 | } |