1 /*- 2 * Copyright (c) 1980, 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static char copyright[] = 36 "@(#) Copyright (c) 1980, 1992, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; 42 #endif /* not lint */ 43 44 #include <sys/param.h> 45 46 #include <nlist.h> 47 #include <signal.h> 48 #include <stdio.h> 49 #include "systat.h" 50 #include "extern.h" 51 52 static struct nlist namelist[] = { 53 #define X_FIRST 0 54 #define X_HZ 0 55 { "_hz" }, 56 #define X_STATHZ 1 57 { "_stathz" }, 58 { "" } 59 }; 60 static int dellave; 61 62 kvm_t *kd; 63 sig_t sigtstpdfl; 64 double avenrun[3]; 65 int col; 66 int naptime = 5; 67 int verbose = 1; /* to report kvm read errs */ 68 int hz, stathz; 69 char c; 70 char *namp; 71 char hostname[MAXHOSTNAMELEN]; 72 WINDOW *wnd; 73 int CMDLINE; 74 75 static WINDOW *wload; /* one line window for load average */ 76 77 void 78 main(argc, argv) 79 int argc; 80 char **argv; 81 { 82 char errbuf[80]; 83 84 argc--, argv++; 85 while (argc > 0) { 86 if (argv[0][0] == '-') { 87 struct cmdtab *p; 88 89 p = lookup(&argv[0][1]); 90 if (p == (struct cmdtab *)-1) { 91 fprintf(stderr, "%s: unknown request\n", 92 &argv[0][1]); 93 exit(1); 94 } 95 curcmd = p; 96 } else { 97 naptime = atoi(argv[0]); 98 if (naptime <= 0) 99 naptime = 5; 100 } 101 argc--, argv++; 102 } 103 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); 104 if (kd == NULL) { 105 error("%s", errbuf); 106 exit(1); 107 } 108 if (kvm_nlist(kd, namelist)) { 109 nlisterr(namelist); 110 exit(1); 111 } 112 if (namelist[X_FIRST].n_type == 0) { 113 fprintf(stderr, "couldn't read namelist.\n"); 114 exit(1); 115 } 116 signal(SIGINT, die); 117 signal(SIGQUIT, die); 118 signal(SIGTERM, die); 119 120 /* 121 * Initialize display. Load average appears in a one line 122 * window of its own. Current command's display appears in 123 * an overlapping sub-window of stdscr configured by the display 124 * routines to minimize update work by curses. 125 */ 126 initscr(); 127 CMDLINE = LINES - 1; 128 wnd = (*curcmd->c_open)(); 129 if (wnd == NULL) { 130 fprintf(stderr, "Couldn't initialize display.\n"); 131 die(0); 132 } 133 wload = newwin(1, 0, 3, 20); 134 if (wload == NULL) { 135 fprintf(stderr, "Couldn't set up load average window.\n"); 136 die(0); 137 } 138 gethostname(hostname, sizeof (hostname)); 139 NREAD(X_HZ, &hz, LONG); 140 NREAD(X_STATHZ, &stathz, LONG); 141 (*curcmd->c_init)(); 142 curcmd->c_flags |= CF_INIT; 143 labels(); 144 145 dellave = 0.0; 146 147 signal(SIGALRM, display); 148 display(0); 149 noecho(); 150 crmode(); 151 keyboard(); 152 /*NOTREACHED*/ 153 } 154 155 void 156 labels() 157 { 158 if (curcmd->c_flags & CF_LOADAV) { 159 mvaddstr(2, 20, 160 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); 161 mvaddstr(3, 5, "Load Average"); 162 } 163 (*curcmd->c_label)(); 164 #ifdef notdef 165 mvprintw(21, 25, "CPU usage on %s", hostname); 166 #endif 167 refresh(); 168 } 169 170 void 171 display(signo) 172 int signo; 173 { 174 register int i, j; 175 176 /* Get the load average over the last minute. */ 177 (void) getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])); 178 (*curcmd->c_fetch)(); 179 if (curcmd->c_flags & CF_LOADAV) { 180 j = 5.0*avenrun[0] + 0.5; 181 dellave -= avenrun[0]; 182 if (dellave >= 0.0) 183 c = '<'; 184 else { 185 c = '>'; 186 dellave = -dellave; 187 } 188 if (dellave < 0.1) 189 c = '|'; 190 dellave = avenrun[0]; 191 wmove(wload, 0, 0); wclrtoeol(wload); 192 for (i = (j > 50) ? 50 : j; i > 0; i--) 193 waddch(wload, c); 194 if (j > 50) 195 wprintw(wload, " %4.1f", avenrun[0]); 196 } 197 (*curcmd->c_refresh)(); 198 if (curcmd->c_flags & CF_LOADAV) 199 wrefresh(wload); 200 wrefresh(wnd); 201 move(CMDLINE, col); 202 refresh(); 203 alarm(naptime); 204 } 205 206 void 207 load() 208 { 209 210 (void) getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])); 211 mvprintw(CMDLINE, 0, "%4.1f %4.1f %4.1f", 212 avenrun[0], avenrun[1], avenrun[2]); 213 clrtoeol(); 214 } 215 216 void 217 die(signo) 218 int signo; 219 { 220 move(CMDLINE, 0); 221 clrtoeol(); 222 refresh(); 223 endwin(); 224 exit(0); 225 } 226 227 #if __STDC__ 228 #include <stdarg.h> 229 #else 230 #include <varargs.h> 231 #endif 232 233 #if __STDC__ 234 void 235 error(const char *fmt, ...) 236 #else 237 void 238 error(fmt, va_alist) 239 char *fmt; 240 va_dcl 241 #endif 242 { 243 va_list ap; 244 char buf[255]; 245 int oy, ox; 246 #if __STDC__ 247 va_start(ap, fmt); 248 #else 249 va_start(ap); 250 #endif 251 252 if (wnd) { 253 getyx(stdscr, oy, ox); 254 (void) vsprintf(buf, fmt, ap); 255 clrtoeol(); 256 standout(); 257 mvaddstr(CMDLINE, 0, buf); 258 standend(); 259 move(oy, ox); 260 refresh(); 261 } else { 262 (void) vfprintf(stderr, fmt, ap); 263 fprintf(stderr, "\n"); 264 } 265 va_end(ap); 266 } 267 268 void 269 nlisterr(namelist) 270 struct nlist namelist[]; 271 { 272 int i, n; 273 274 n = 0; 275 clear(); 276 mvprintw(2, 10, "systat: nlist: can't find following symbols:"); 277 for (i = 0; 278 namelist[i].n_name != NULL && *namelist[i].n_name != '\0'; i++) 279 if (namelist[i].n_value == 0) 280 mvprintw(2 + ++n, 10, "%s", namelist[i].n_name); 281 move(CMDLINE, 0); 282 clrtoeol(); 283 refresh(); 284 endwin(); 285 exit(1); 286 } 287