1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-08 23:06:56 +00:00
freebsd-ports/sysutils/wmmon/files/patch-ad
Steve Price 4d8e69bf0e Fix a security hole where a user can obtain kmem group privs. Note
patch-ad and patch-ae both patches the same file, so I combined them
and removed patch-ae.  The maintainer might want to look into patch-ad
some more since patch-ae did the same as patch-ad one one had the lines
before the offending block of code and one after.  I left both sets
since it didn't appear to affect operation any.

PR:		15790
Submitted by:	maintainer
1999-12-31 20:12:45 +00:00

885 lines
23 KiB
Plaintext

*** wmmon.c.orig Tue May 19 16:13:16 1998
--- wmmon.c Fri Dec 31 12:05:34 1999
***************
*** 28,33 ****
--- 28,44 ----
Changes:
----
+ 12/01/1999 (Stephen Kiernan, sk-ports@vegamuse.org)
+ * Change to revert to real userid and groupid
+ after kvm_openfiles is accomplished.
+ (Patch from Steve Reid, sreid@sea-to-sky.net)
+ 05/24/1999 (Stephen Kiernan, sk-ports@vegamuse.org)
+ * Ported to FreeBSD 4.0
+ 12/11/1998 (Stephen Kiernan, sk-ports@vegamuse.org)
+ * Ported to FreeBSD 2.2, 3.0
+ * Based on code from the FreeBSD 2.2 version of top
+ by Christos Zoulas, Steven Wallace, and
+ Wolfram Schneider
18/05/1998 (Antoine Nulle, warp@xs4all.nl)
* MEM/SWAP/UPTIME only updated when visible
* Using global file descriptors to reduce file
***************
*** 72,81 ****
--- 83,109 ----
#include <fcntl.h>
#include <unistd.h>
+ #include <errno.h>
+
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/types.h>
+ #include <kvm.h>
+ #include <limits.h>
+ #include <osreldate.h>
+ #include <sys/conf.h>
+ #include <sys/dkstat.h>
+ #if __FreeBSD_version >= 300000
+ #include <devstat.h>
+ #endif
+ #include <sys/sysctl.h>
+ #include <sys/time.h>
+ #if __FreeBSD_version >= 400000 && __FreeBSD_version < 400005
+ #include <sys/rlist.h>
+ #endif
+ #include <sys/vmmeter.h>
+
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
***************
*** 106,117 ****
--- 134,193 ----
FILE *fp_stat;
FILE *fp_loadavg;
+ kvm_t *kvmd = NULL;
+ struct nlist nl[] = {
+ #define N_CNT 0
+ { "_cnt" },
+ #define N_BUFSPACE 1
+ { "_bufspace" },
+ #define N_CP_TIME 2
+ { "_cp_time" },
+ #define N_AVERUN 3
+ { "_averunnable" },
+ #if __FreeBSD_version >= 300000
+ #define N_TK_NIN 4
+ { "_tk_nin" },
+ #define N_TK_NOUT 5
+ { "_tk_nout" },
+ #else
+ #define N_DK_NDRIVE 4
+ { "_dk_ndrive" },
+ #define N_DK_WDS 5
+ { "_dk_wds" },
+ #endif
+ #if __FreeBSD_version < 400000
+ #define VM_SWAPLIST 6
+ { "_swaplist" },
+ #define VM_SWDEVT 7
+ { "_swdevt" },
+ #define VM_NSWAP 8
+ { "_nswap" },
+ #define VM_NSWDEV 9
+ { "_nswdev" },
+ #define VM_DMMAX 10
+ { "_dmmax" },
+ #endif
+ { "" }
+ };
+ int psize;
+ int pshift;
+ long *cur_dk_wds;
+ long *last_dk_wds;
+ int ndrives;
+ char errbuf[_POSIX2_LINE_MAX];
+ static int swappgsin = -1;
+ static int swappgsout = -1;
+
/* functions */
void usage(void);
void printversion(void);
void DrawStats(int *, int, int, int, int);
void DrawStats_io(int *, int, int, int, int);
+ #if defined(__FreeBSD__) || defined(__NetBSD__)
+ int swapmode( long *retavail, long *retfree);
+ #endif /* __FreeBSD__ || __NetBSD__ */
+
void wmmon_routine(int, char **);
void main(int argc, char *argv[]) {
***************
*** 154,159 ****
--- 230,241 ----
}
}
+ if( checkversion() < 0 )
+ {
+ fprintf( stderr, devstat_errbuf );
+ exit(1);
+ }
+
wmmon_routine(argc, argv);
}
***************
*** 213,238 ****
long istat;
long idle;
! FILE *fp;
! char temp[128];
char *p;
! int xpm_X = 0, xpm_Y = 0;
long online_time = 0;
long ref_time = 0;
long cnt_time;
!
! fp = fopen("/proc/uptime", "r");
! fp_meminfo = fopen("/proc/meminfo", "r");
! fp_loadavg = fopen("/proc/loadavg", "r");
! fp_stat = fopen("/proc/stat", "r");
!
! if (fp) {
! fscanf(fp, "%ld", &online_time);
ref_time = time(0);
! fclose(fp);
}
for (i=0; i<MAX_STAT_DEVICES; i++) {
--- 295,366 ----
long istat;
long idle;
! int mib[2];
! size_t size;
! struct timeval boottime;
char *p;
! int xpm_X = 0, xpm_Y = 0;
long online_time = 0;
long ref_time = 0;
long cnt_time;
! mib[0] = CTL_KERN;
! mib[1] = KERN_BOOTTIME;
! size = sizeof(boottime);
! if ((sysctl(mib, 2, &boottime, &size, NULL, 0)!=-1) &&
! (boottime.tv_sec != 0)) {
ref_time = time(0);
! online_time = ref_time - boottime.tv_sec + 30;
! }
!
! psize = getpagesize();
! for (pshift = 0, psize = getpagesize(); psize>1; pshift++, psize>>=1)
! continue;
! pshift -= 10;
! psize = getpagesize();
!
! if (setgid(getgid()) != 0) exit(1); /* We're sgid kmem. Give up privs. */
! if (setuid(getuid()) != 0) exit(1); /* If we're suid, give that up too. */
!
! if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
! if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
!
! /* We're sgid kmem. Give up privs. */
! if (setgid(getgid()) != 0) { perror("setgid"); exit(errno); }
!
! /* If we're suid, give that up too. */
! if (setuid(getuid()) != 0) { perror("seguid"); exit(errno); }
!
! if (kvmd) {
! if (kvm_nlist(kvmd, nl) >= 0) {
! struct nlist *nlp;
!
! for( nlp = nl; *nlp->n_name != '\0'; nlp++ ) {
! if( nlp->n_type == 0 )
! fprintf (stderr, "kvm_nlist: Symbol '%s' not found\n", nlp->n_name);
! }
!
! #if __FreeBSD_version >= 300000
! ndrives = getnumdevs();
! #else
! if (nl[0].n_type != 0) {
! (void) kvm_read(kvmd, nl[N_DK_NDRIVE].n_value, (char *)&ndrives, sizeof(ndrives));
! if (ndrives > 0) {
! cur_dk_wds = calloc(ndrives, sizeof(long));
! last_dk_wds = calloc(ndrives, sizeof(long));
! bzero(last_dk_wds, sizeof(long) * ndrives);
! }
! #endif
! fprintf (stderr, "Monitoring %d devices for activity.\n", ndrives);
! #if __FreeBSD_version < 300000
! }
! #endif
! }
! else {
! fprintf( stderr, "kvm_nlist: %s\n", kvm_geterr(kvmd) );
! }
}
for (i=0; i<MAX_STAT_DEVICES; i++) {
***************
*** 246,261 ****
if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
! strcpy(temp, "/etc/wmmonrc");
! parse_rcfile(temp, wmmon_keys);
! p = getenv("HOME");
! strcpy(temp, p);
! strcat(temp, "/.wmmonrc");
! parse_rcfile(temp, wmmon_keys);
! strcpy(temp, "/etc/wmmonrc.fixed");
! parse_rcfile(temp, wmmon_keys);
stat_online = checksysdevs();
--- 374,393 ----
if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
! parse_rcfile("/etc/wmmonrc", wmmon_keys);
! if ((p = getenv("HOME")) != NULL) {
! #define RCFILE "/.wmmonrc"
! int tmpsize = strlen(p) + sizeof(RCFILE) + 1;
! char *tmp = malloc(tmpsize);
! if (tmp != NULL) {
! snprintf(tmp, tmpsize, "%s" RCFILE, p);
! parse_rcfile(tmp, wmmon_keys);
! free(tmp);
! }
! }
! parse_rcfile("/etc/wmmonrc.fixed", wmmon_keys);
stat_online = checksysdevs();
***************
*** 484,489 ****
--- 616,626 ----
st->rt_idle = idle - st->idlelast;
st->idlelast = idle;
+ /* There's a problem here with values crossing
+ the max long size barrier becoming negative --
+ things restabilize after some time, but a
+ better solution needs to be designed
+ */
st->rt_stat = istat - st->statlast;
st->statlast = istat;
***************
*** 499,543 ****
void update_stat_mem(stat_dev *st, stat_dev *st2) {
! char temp[128];
! unsigned long free, shared, buffers, cached;
! freopen("/proc/meminfo", "r", fp_meminfo);
! while (fgets(temp, 128, fp_meminfo)) {
! if (strstr(temp, "Mem:")) {
! sscanf(temp, "Mem: %ld %ld %ld %ld %ld %ld",
! &st->rt_idle, &st->rt_stat,
! &free, &shared, &buffers, &cached);
! st->rt_idle >>= 10;
! st->rt_stat -= buffers+cached;
! st->rt_stat >>= 10;
! // break;
! }
! if (strstr(temp, "Swap:")) {
! sscanf(temp, "Swap: %ld %ld", &st2->rt_idle, &st2->rt_stat);
! st2->rt_idle >>= 10;
! st2->rt_stat >>= 10;
! break;
}
}
}
void update_stat_swp(stat_dev *st) {
! char temp[128];
! fseek(fp_meminfo, 0, SEEK_SET);
! while (fgets(temp, 128, fp_meminfo)) {
! if (strstr(temp, "Swap:")) {
! sscanf(temp, "Swap: %ld %ld", &st->rt_idle, &st->rt_stat);
! st->rt_idle >>= 10;
! st->rt_stat >>= 10;
! break;
}
}
}
/*******************************************************************************\
|* get_statistics *|
\*******************************************************************************/
--- 636,890 ----
void update_stat_mem(stat_dev *st, stat_dev *st2) {
! unsigned long buffers;
! if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
! if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
! if (kvmd) {
! if (kvm_nlist(kvmd, nl) >= 0) {
! if (nl[0].n_type != 0) {
! static int first_time_done = 0;
! int dpagein, dpageout;
! struct vmmeter sum;
!
! if ((kvm_read(kvmd, nl[N_CNT].n_value, (char *)&sum, sizeof(sum))==sizeof(sum)) &&
! (kvm_read(kvmd, nl[N_BUFSPACE].n_value, (char *)&buffers, sizeof(buffers))==sizeof(buffers))) {
! st->rt_idle = (sum.v_page_count - (buffers/psize) - sum.v_wire_count) << pshift;
! st->rt_stat = sum.v_active_count << pshift;
!
! if (swappgsin < 0) {
! dpagein = 0;
! dpageout = 0;
! }
! else {
! dpagein = (sum.v_swappgsin - swappgsin) << pshift;
! dpageout = (sum.v_swappgsout - swappgsout) << pshift;
! }
! swappgsin = sum.v_swappgsin;
! swappgsout = sum.v_swappgsout;
!
! if ((dpagein>0) || (dpageout>0) || (first_time_done==0)) {
! swapmode(&st2->rt_idle, &st2->rt_stat);
! st2->rt_stat = st2->rt_idle - st2->rt_stat;
! }
! first_time_done = 1;
! }
! }
}
}
}
void update_stat_swp(stat_dev *st) {
! if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
! if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
! if (kvmd) {
! if (kvm_nlist(kvmd, nl) >= 0) {
! if (nl[0].n_type != 0) {
! static int first_time_done = 0;
! int dpagein, dpageout;
!
! struct vmmeter sum;
! if (kvm_read(kvmd, nl[N_CNT].n_value, (char *)&sum, sizeof(sum))==sizeof(sum)) {
! if (swappgsin < 0) {
! dpagein = 0;
! dpageout = 0;
! }
! else {
! dpagein = (sum.v_swappgsin - swappgsin) << pshift;
! dpageout = (sum.v_swappgsout - swappgsout) << pshift;
! }
! swappgsin = sum.v_swappgsin;
! swappgsout = sum.v_swappgsout;
!
! if ((dpagein>0) || (dpageout>0) || (first_time_done==0)) {
! swapmode(&st->rt_idle, &st->rt_stat);
! st->rt_stat = st->rt_idle - st->rt_stat;
! }
! first_time_done = 1;
! }
! }
! }
! }
! }
!
! #if __FreeBSD_version < 400000
! /*
! * swapmode for FreeBSD 2.x and 3.x is based on a program called swapinfo
! * written by Kevin Lahey <kml@rokkaku.atl.ga.us>.
! */
!
! #define SVAR(var) __STRING(var) /* to force expansion */
! #define KGET(idx, var) \
! KGET1(idx, &var, sizeof(var), SVAR(var))
! #define KGET1(idx, p, s, msg) \
! KGET2(nl[idx].n_value, p, s, msg)
! #define KGET2(addr, p, s, msg) \
! if (kvm_read(kvmd, (u_long)(addr), p, s) != s) { \
! return (0); \
! }
! #define KGETRET(addr, p, s, msg) \
! if (kvm_read(kvmd, (u_long)(addr), p, s) != s) { \
! return (0); \
! }
! #endif
!
!
! int swapmode( long *retavail, long *retfree)
! {
! int used, avail;
! #if __FreeBSD_version >= 400000
! struct kvm_swap kvmswap;
! #else
! char *header;
! int hlen, nswap, nswdev, dmmax;
! int i, div, nfree, npfree;
! struct swdevt *sw;
! long blocksize, *perdev;
! u_long ptr;
! struct rlist head;
! # if __FreeBSD_version >= 220000
! struct rlisthdr swaplist;
! # else
! struct rlist *swaplist;
! # endif
! struct rlist *swapptr;
! #endif
!
! /*
! * Counter for error messages. If we reach the limit,
! * stop reading information from swap devices and
! * return zero. This prevent endless 'bad address'
! * messages.
! */
! static int warning = 10;
!
! if (warning <= 0) {
! /* a single warning */
! if (!warning) {
! warning--;
! fprintf(stderr,
! "Too much errors, stop reading swap devices ...\n");
! (void)sleep(3);
! }
! return(0);
! }
! warning--; /* decrease counter, see end of function */
!
! #if __FreeBSD_version >= 400000
! if( kvm_getswapinfo( kvmd, &kvmswap, 1, 0 ) < 0 ) {
! fprintf(stderr, "kvm_getswapinfo failed\n");
! return(0);
! }
!
! *retavail = avail = kvmswap.ksw_total;
! used = kvmswap.ksw_used;
! *retfree = kvmswap.ksw_total - used;
! #else
! KGET(VM_NSWAP, nswap);
! if (!nswap) {
! fprintf(stderr, "No swap space available\n");
! return(0);
! }
!
! KGET(VM_NSWDEV, nswdev);
! KGET(VM_DMMAX, dmmax);
! KGET1(VM_SWAPLIST, &swaplist, sizeof(swaplist), "swaplist");
! if ((sw = (struct swdevt *)malloc(nswdev * sizeof(*sw))) == NULL ||
! (perdev = (long *)malloc(nswdev * sizeof(*perdev))) == NULL)
! {
! perror("malloc");
! exit(1);
! }
! KGET1(VM_SWDEVT, &ptr, sizeof ptr, "swdevt");
! KGET2(ptr, sw, nswdev * sizeof(*sw), "*swdevt");
! /* Count up swap space. */
! nfree = 0;
! memset(perdev, 0, nswdev * sizeof(*perdev));
! #if __FreeBSD_version >= 220000
! swapptr = swaplist.rlh_list;
! while (swapptr) {
! #else
! while (swaplist) {
! #endif
! int top, bottom, next_block;
! #if __FreeBSD_version >= 220000
! KGET2(swapptr, &head, sizeof(struct rlist), "swapptr");
! #else
! KGET2(swaplist, &head, sizeof(struct rlist), "swaplist");
! #endif
!
! top = head.rl_end;
! bottom = head.rl_start;
!
! nfree += top - bottom + 1;
!
! /*
! * Swap space is split up among the configured disks.
! *
! * For interleaved swap devices, the first dmmax blocks
! * of swap space some from the first disk, the next dmmax
! * blocks from the next, and so on up to nswap blocks.
! *
! * The list of free space joins adjacent free blocks,
! * ignoring device boundries. If we want to keep track
! * of this information per device, we'll just have to
! * extract it ourselves.
! */
!
! while (top / dmmax != bottom / dmmax) {
! next_block = ((bottom + dmmax) / dmmax);
! perdev[(bottom / dmmax) % nswdev] +=
! next_block * dmmax - bottom;
! bottom = next_block * dmmax;
}
+ perdev[(bottom / dmmax) % nswdev] +=
+ top - bottom + 1;
+
+ #if __FreeBSD_version >= 220000
+ swapptr = head.rl_next;
+ #else
+ swaplist = head.rl_next;
+ #endif
+ }
+
+ header = getbsize(&hlen, &blocksize);
+ div = blocksize / 512;
+ avail = npfree = 0;
+ for (i = 0; i < nswdev; i++) {
+ int xsize, xfree;
+
+ /*
+ * Don't report statistics for partitions which have not
+ * yet been activated via swapon(8).
+ */
+
+ xsize = sw[i].sw_nblks;
+ xfree = perdev[i];
+ used = xsize - xfree;
+ npfree++;
+ avail += xsize;
}
+ /*
+ * If only one partition has been set up via swapon(8), we don't
+ * need to bother with totals.
+ */
+ *retavail = avail / 2;
+ *retfree = nfree / 2;
+ used = avail - nfree;
+ free(sw); free(perdev);
+ #endif /* __FreeBSD_version >= 400000 */
+
+ /* increase counter, no errors occurs */
+ warning++;
+
+ return (int)(((double)used / (double)avail * 100.0) + 0.5);
}
+
+
/*******************************************************************************\
|* get_statistics *|
\*******************************************************************************/
***************
*** 545,554 ****
void get_statistics(char *devname, long *is, long *ds, long *idle) {
int i;
! char temp[128];
! char *p;
! char *tokens = " \t\n";
! float f;
long maxdiskio=0;
*is = 0;
--- 892,899 ----
void get_statistics(char *devname, long *is, long *ds, long *idle) {
int i;
! long averun[3];
! long cp_time[CPUSTATES];
long maxdiskio=0;
*is = 0;
***************
*** 556,592 ****
*idle = 0;
if (!strncmp(devname, "cpu", 3)) {
! fseek(fp_stat, 0, SEEK_SET);
! while (fgets(temp, 128, fp_stat)) {
! if (strstr(temp, "cpu")) {
! p = strtok(temp, tokens);
! /* 1..3, 4 == idle, we don't want idle! */
! for (i=0; i<3; i++) {
! p = strtok(NULL, tokens);
! *ds += atol(p);
! }
! p = strtok(NULL, tokens);
! *idle = atol(p);
! }
! }
! fp_loadavg = freopen("/proc/loadavg", "r", fp_loadavg);
! fscanf(fp_loadavg, "%f", &f);
! *is = (long) (100 * f);
}
if (!strncmp(devname, "i/o", 3)) {
! fseek(fp_stat, 0, SEEK_SET);
! while (fgets(temp, 128, fp_stat)) {
! if (strstr(temp, "disk_rio") || strstr(temp, "disk_wio")) {
! p = strtok(temp, tokens);
! /* 1..4 */
! for (i=0; i<4; i++) {
! p = strtok(NULL, tokens);
! *ds += atol(p);
}
}
}
if (*ds > maxdiskio) maxdiskio = *ds;
}
}
--- 901,1105 ----
*idle = 0;
if (!strncmp(devname, "cpu", 3)) {
! if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
! if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
! if (kvmd) {
! if (kvm_nlist(kvmd, nl) >= 0) {
! if (nl[0].n_type != 0) {
! if ((kvm_read(kvmd, nl[N_CP_TIME].n_value, (char *)&cp_time, sizeof(cp_time))==sizeof(cp_time)) &&
! (kvm_read(kvmd, nl[N_AVERUN].n_value, (char *)&averun, sizeof(averun))==sizeof(averun))) {
! *is = (long) (100 * ((double)averun[0] / FSCALE));
!
! for (i = 0; i < CPUSTATES; i++) {
! if (i != CP_IDLE) *ds += cp_time[i];
! }
! *idle = cp_time[CP_IDLE];
! }
! }
! }
! }
}
if (!strncmp(devname, "i/o", 3)) {
+ #if __FreeBSD_version < 300000
+ if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
+ if (kvmd==NULL) { fprintf(stderr, "kvm_openfiles: %s\n", errbuf); exit(errno); }
+ if (kvmd) {
+ if (kvm_nlist(kvmd, nl) >= 0) {
+ if (nl[0].n_type != 0) {
+ if (kvm_read(kvmd, nl[N_DK_WDS].n_value, (char *)cur_dk_wds, ndrives * sizeof(long))==(ndrives*sizeof(long))) {
+ for (i = 0; i < ndrives; i++) {
+ *ds += cur_dk_wds[i];
+ }
+ }
+ }
+ }
+ }
+ #else
+ static int initted = 0;
+ static struct statinfo last;
+ static struct statinfo cur;
+ int ndevs = getnumdevs();
+ int gotdevs = 0;
+ long generation;
+ int num_devices_specified = 0;
+ int num_selected;
+ int num_selections;
+ int maxshowdevs = 10;
+ int num_matches = 0;
+ struct devstat_match *matches = NULL;
+ struct device_selection *dev_select = NULL;
+ char **specified_devices;
+ long select_generation;
+
+ if( !initted )
+ {
+ bzero( &cur, sizeof(cur) );
+ bzero( &last, sizeof(cur) );
+
+ cur.dinfo = (struct devinfo *)malloc( sizeof(struct devinfo) );
+ last.dinfo = (struct devinfo *)malloc( sizeof(struct devinfo) );
! bzero( cur.dinfo, sizeof(struct devinfo) );
! bzero( last.dinfo, sizeof(struct devinfo) );
!
! specified_devices = (char **)malloc(sizeof(char *));
! }
! else
! {
! struct devinfo *tmp;
!
! if (kvmd==NULL) kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
! if (kvmd==NULL)
! {
! fprintf(stderr, "kvm_openfiles: %s\n", errbuf);
! exit(errno);
! }
! else
! {
! (void)kvm_read( kvmd, nl[N_TK_NIN].n_value, &cur.tk_nin,
! sizeof(cur.tk_nin) );
! (void)kvm_read( kvmd, nl[N_TK_NOUT].n_value, &cur.tk_nout,
! sizeof(cur.tk_nout) );
! (void)kvm_read( kvmd, nl[N_CP_TIME].n_value,
! cur.cp_time, sizeof(cur.cp_time) );
! }
!
! tmp = last.dinfo;
! memcpy( &last, &cur, sizeof(cur) );
! cur.dinfo = tmp;
!
! last.busy_time = cur.busy_time;
! }
!
! if( !gotdevs && ( getdevs( &cur ) >= 0 ) )
! gotdevs = 1;
!
! if( gotdevs )
! {
! generation = cur.dinfo->generation;
! ndevs = cur.dinfo->numdevs;
!
! if( !initted )
! {
! selectdevs( &dev_select, &num_selected, &num_selections,
! &select_generation, generation, cur.dinfo->devices,
! ndevs, matches, num_matches, specified_devices,
! num_devices_specified, DS_SELECT_ONLY, maxshowdevs,
! 1 );
! }
! else
! {
! struct devinfo *tmpinfo;
! long tmp;
!
! switch( getdevs( &cur ) )
! {
! case 1:
! selectdevs( &dev_select, &num_selected,
! &num_selections, &select_generation,
! generation, cur.dinfo->devices,
! ndevs, matches, num_matches,
! specified_devices,
! num_devices_specified,
! DS_SELECT_ONLY,
! maxshowdevs, 1 );
!
! if (kvmd==NULL)
! {
! fprintf(stderr, "kvm_openfiles: %s\n", errbuf);
! exit(errno);
! }
! else
! {
! (void)kvm_read( kvmd, nl[N_TK_NIN].n_value, &cur.tk_nin,
! sizeof(cur.tk_nin) );
! (void)kvm_read( kvmd, nl[N_TK_NOUT].n_value, &cur.tk_nout,
! sizeof(cur.tk_nout) );
! (void)kvm_read( kvmd, nl[N_CP_TIME].n_value,
! cur.cp_time, sizeof(cur.cp_time) );
! }
!
! tmpinfo = last.dinfo;
! memcpy( &last, &cur, sizeof(cur) );
! cur.dinfo = tmpinfo;
!
! last.busy_time = cur.busy_time;
! break;
! default:
! break;
! }
!
! selectdevs( &dev_select, &num_selected, &num_selections,
! &select_generation, generation, cur.dinfo->devices,
! ndevs, matches, num_matches, specified_devices,
! num_devices_specified, DS_SELECT_ONLY, maxshowdevs,
! 1 );
!
! tmp = cur.tk_nin;
! cur.tk_nin -= last.tk_nin;
! last.tk_nin = tmp;
! tmp = cur.tk_nout;
! cur.tk_nout -= last.tk_nout;
! last.tk_nout = tmp;
!
! {
! register int dn;
! long double transfers_per_second;
! long double kb_per_transfer, mb_per_second;
! u_int64_t total_bytes, total_transfers, total_blocks;
! long double busy_seconds;
! long double blocks_per_second, ms_per_transaction;
!
! busy_seconds = compute_etime( cur.busy_time, last.busy_time );
!
! for( dn = 0; dn < ndevs; dn++ )
! {
! int di = dev_select[dn].position;
!
! if( compute_stats( &cur.dinfo->devices[di],
! &last.dinfo->devices[di],
! busy_seconds,
! &total_bytes,
! &total_transfers,
! &total_blocks,
! &kb_per_transfer,
! &transfers_per_second,
! &mb_per_second,
! &blocks_per_second,
! &ms_per_transaction ) == 0 )
! {
! *ds += total_blocks;
! }
! }
}
}
+ initted = 1;
}
+
+ if( dev_select )
+ free( dev_select );
+ #endif
if (*ds > maxdiskio) maxdiskio = *ds;
}
}
***************
*** 597,605 ****
int checksysdevs(void) {
! strcpy(stat_device[0].name, "cpu0");
! strcpy(stat_device[1].name, "i/o");
! strcpy(stat_device[2].name, "sys");
return 3;
}
--- 1110,1118 ----
int checksysdevs(void) {
! strncpy(stat_device[0].name, "cpu0", 5);
! strncpy(stat_device[1].name, "i/o", 5);
! strncpy(stat_device[2].name, "sys", 5);
return 3;
}
***************
*** 638,643 ****
--- 1151,1157 ----
int *p;
int d;
+ /* printf ("size = %d, num = %d\n", size, num); */
pixels_per_byte = 100;
p = his;
for (j=0; j<num; j++) {