1 /*- 2 * Copyright (c) 1980, 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980, 1992 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)main.c 5.16 (Berkeley) 05/21/93"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 20 #include <nlist.h> 21 #include <signal.h> 22 #include <stdio.h> 23 #include "systat.h" 24 #include "extern.h" 25 26 static struct nlist namelist[] = { 27 #define X_FIRST 0 28 #define X_HZ 0 29 { "_hz" }, 30 #define X_STATHZ 1 31 { "_stathz" }, 32 { "" } 33 }; 34 static int dellave; 35 36 kvm_t *kd; 37 sig_t sigtstpdfl; 38 double avenrun[3]; 39 int col; 40 int naptime = 5; 41 int verbose = 1; /* to report kvm read errs */ 42 int hz, stathz; 43 char c; 44 char *namp; 45 char hostname[MAXHOSTNAMELEN]; 46 WINDOW *wnd; 47 int CMDLINE; 48 49 static WINDOW *wload; /* one line window for load average */ 50 51 void 52 main(argc, argv) 53 int argc; 54 char **argv; 55 { 56 char errbuf[80]; 57 58 argc--, argv++; 59 while (argc > 0) { 60 if (argv[0][0] == '-') { 61 struct cmdtab *p; 62 63 p = lookup(&argv[0][1]); 64 if (p == (struct cmdtab *)-1) { 65 fprintf(stderr, "%s: unknown request\n", 66 &argv[0][1]); 67 exit(1); 68 } 69 curcmd = p; 70 } else { 71 naptime = atoi(argv[0]); 72 if (naptime <= 0) 73 naptime = 5; 74 } 75 argc--, argv++; 76 } 77 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); 78 if (kd == NULL) { 79 error("%s", errbuf); 80 exit(1); 81 } 82 if (kvm_nlist(kd, namelist)) { 83 nlisterr(namelist); 84 exit(1); 85 } 86 if (namelist[X_FIRST].n_type == 0) { 87 fprintf(stderr, "couldn't read namelist.\n"); 88 exit(1); 89 } 90 signal(SIGINT, die); 91 signal(SIGQUIT, die); 92 signal(SIGTERM, die); 93 94 /* 95 * Initialize display. Load average appears in a one line 96 * window of its own. Current command's display appears in 97 * an overlapping sub-window of stdscr configured by the display 98 * routines to minimize update work by curses. 99 */ 100 initscr(); 101 CMDLINE = LINES - 1; 102 wnd = (*curcmd->c_open)(); 103 if (wnd == NULL) { 104 fprintf(stderr, "Couldn't initialize display.\n"); 105 die(0); 106 } 107 wload = newwin(1, 0, 3, 20); 108 if (wload == NULL) { 109 fprintf(stderr, "Couldn't set up load average window.\n"); 110 die(0); 111 } 112 gethostname(hostname, sizeof (hostname)); 113 NREAD(X_HZ, &hz, LONG); 114 NREAD(X_STATHZ, &stathz, LONG); 115 (*curcmd->c_init)(); 116 curcmd->c_flags |= CF_INIT; 117 labels(); 118 119 dellave = 0.0; 120 121 signal(SIGALRM, display); 122 display(0); 123 noecho(); 124 crmode(); 125 keyboard(); 126 /*NOTREACHED*/ 127 } 128 129 void 130 labels() 131 { 132 if (curcmd->c_flags & CF_LOADAV) { 133 mvaddstr(2, 20, 134 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); 135 mvaddstr(3, 5, "Load Average"); 136 } 137 (*curcmd->c_label)(); 138 #ifdef notdef 139 mvprintw(21, 25, "CPU usage on %s", hostname); 140 #endif 141 refresh(); 142 } 143 144 void 145 display(signo) 146 int signo; 147 { 148 register int i, j; 149 150 /* Get the load average over the last minute. */ 151 (void) getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])); 152 (*curcmd->c_fetch)(); 153 if (curcmd->c_flags & CF_LOADAV) { 154 j = 5.0*avenrun[0] + 0.5; 155 dellave -= avenrun[0]; 156 if (dellave >= 0.0) 157 c = '<'; 158 else { 159 c = '>'; 160 dellave = -dellave; 161 } 162 if (dellave < 0.1) 163 c = '|'; 164 dellave = avenrun[0]; 165 wmove(wload, 0, 0); wclrtoeol(wload); 166 for (i = (j > 50) ? 50 : j; i > 0; i--) 167 waddch(wload, c); 168 if (j > 50) 169 wprintw(wload, " %4.1f", avenrun[0]); 170 } 171 (*curcmd->c_refresh)(); 172 if (curcmd->c_flags & CF_LOADAV) 173 wrefresh(wload); 174 wrefresh(wnd); 175 move(CMDLINE, col); 176 refresh(); 177 alarm(naptime); 178 } 179 180 void 181 load() 182 { 183 184 (void) getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])); 185 mvprintw(CMDLINE, 0, "%4.1f %4.1f %4.1f", 186 avenrun[0], avenrun[1], avenrun[2]); 187 clrtoeol(); 188 } 189 190 void 191 die(signo) 192 int signo; 193 { 194 move(CMDLINE, 0); 195 clrtoeol(); 196 refresh(); 197 endwin(); 198 exit(0); 199 } 200 201 #if __STDC__ 202 #include <stdarg.h> 203 #else 204 #include <varargs.h> 205 #endif 206 207 #if __STDC__ 208 void 209 error(const char *fmt, ...) 210 #else 211 void 212 error(fmt, va_alist) 213 char *fmt; 214 va_dcl 215 #endif 216 { 217 va_list ap; 218 char buf[255]; 219 int oy, ox; 220 #if __STDC__ 221 va_start(ap, fmt); 222 #else 223 va_start(ap); 224 #endif 225 226 if (wnd) { 227 getyx(stdscr, oy, ox); 228 (void) vsprintf(buf, fmt, ap); 229 clrtoeol(); 230 standout(); 231 mvaddstr(CMDLINE, 0, buf); 232 standend(); 233 move(oy, ox); 234 refresh(); 235 } else { 236 (void) vfprintf(stderr, fmt, ap); 237 fprintf(stderr, "\n"); 238 } 239 va_end(ap); 240 } 241 242 void 243 nlisterr(namelist) 244 struct nlist namelist[]; 245 { 246 int i, n; 247 248 n = 0; 249 clear(); 250 mvprintw(2, 10, "systat: nlist: can't find following symbols:"); 251 for (i = 0; 252 namelist[i].n_name != NULL && *namelist[i].n_name != '\0'; i++) 253 if (namelist[i].n_value == 0) 254 mvprintw(2 + ++n, 10, "%s", namelist[i].n_name); 255 move(CMDLINE, 0); 256 clrtoeol(); 257 refresh(); 258 endwin(); 259 exit(1); 260 } 261