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