ruptime(1) limits one to too few hosts +FIX
Karl Kleinpaste
karl at triceratops.cis.ohio-state.edu
Wed Mar 16 02:15:27 AEST 1988
Index: ucb/ruptime.c
Description:
Ruptime believes that no local network will ever grow to
more than 100 hosts. This is defined by the constant NHOSTS
in ruptime.c, line 24. We trounced on this limit quite some
time ago. When we reported this bug, our vendor chose not to
take the opportunity to fix ruptime The Right Way, but rather
merely knocked the NHOSTS limit up a ways. (Admittedly, QUITE
a ways.) That's The Wrong Way, because the new limit is still
too small for our plans a couple years down the line. I spent
less than an hour with the vanilla 4.3BSD ucb/ruptime.c and
fixed it so that it uses malloc() to get the space required
dynamically.
Repeat-By:
Install a network with 500 hosts on it. Run ruptime. Get the
hopelessly weak diagnostic
too many hosts
Fix:
Install the following context diff to ucb/ruptime.c. It works
just fine for arbitrary numbers of hosts. If you've got a
million hosts and enough VM, it'll still work. And it even
passes lint without so much as a whimper now as well.
--Karl
*** ruptime.c~ Tue Mar 15 10:24:00 1988
--- ruptime.c Tue Mar 15 10:51:11 1988
***************
*** 21,27
DIR *dirp;
! #define NHOSTS 100
int nhosts;
struct hs {
struct whod *hs_wd;
--- 21,30 -----
DIR *dirp;
! /*
! * No braindead arbitrary size limits!
! * Insist on total generality!
! */
int nhosts;
struct hs {
struct whod *hs_wd;
***************
*** 26,32
struct hs {
struct whod *hs_wd;
int hs_nusers;
! } hs[NHOSTS];
struct whod awhod;
int hscmp(), ucmp(), lcmp(), tcmp();
--- 29,38 -----
struct hs {
struct whod *hs_wd;
int hs_nusers;
! struct hs *hs_next;
! };
! struct hs *hs_head = (struct hs *) NULL,
! **hs;
struct whod awhod;
int hscmp(), ucmp(), lcmp(), tcmp();
***************
*** 30,35
struct whod awhod;
int hscmp(), ucmp(), lcmp(), tcmp();
#define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
#define RWHODIR "/usr/spool/rwho"
--- 36,43 -----
struct whod awhod;
int hscmp(), ucmp(), lcmp(), tcmp();
+ extern time_t time();
+
#define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
#define RWHODIR "/usr/spool/rwho"
***************
*** 49,55
int f, i, t;
char buf[sizeof(struct whod)]; int cc;
char *name;
! register struct hs *hsp = hs;
register struct whod *wd;
register struct whoent *we;
int maxloadav = 0;
--- 57,63 -----
int f, i, t;
char buf[sizeof(struct whod)]; int cc;
char *name;
! register struct hs *hsp;
register struct whod *wd;
register struct whoent *we;
int maxloadav = 0;
***************
*** 55,60
int maxloadav = 0;
int (*cmp)() = hscmp;
name = *argv;
while (*++argv)
while (**argv)
--- 63,69 -----
int maxloadav = 0;
int (*cmp)() = hscmp;
+ argc = argc;
name = *argv;
while (*++argv)
while (**argv)
***************
*** 81,87
name);
exit (1);
}
! time(&t);
if (chdir(RWHODIR) < 0) {
perror(RWHODIR);
exit(1);
--- 90,96 -----
name);
exit (1);
}
! (void) time((time_t *) &t);
if (chdir(RWHODIR) < 0) {
perror(RWHODIR);
exit(1);
***************
*** 96,105
continue;
if (strncmp(dp->d_name, "whod.", 5))
continue;
- if (nhosts == NHOSTS) {
- fprintf(stderr, "too many hosts\n");
- exit(1);
- }
f = open(dp->d_name, 0);
if (f > 0) {
cc = read(f, buf, sizeof(struct whod));
--- 105,110 -----
continue;
if (strncmp(dp->d_name, "whod.", 5))
continue;
f = open(dp->d_name, 0);
if (f > 0) {
cc = read(f, buf, sizeof(struct whod));
***************
*** 104,109
if (f > 0) {
cc = read(f, buf, sizeof(struct whod));
if (cc >= WHDRSIZE) {
hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);
wd = (struct whod *)buf;
bcopy(buf, hsp->hs_wd, WHDRSIZE);
--- 109,122 -----
if (f > 0) {
cc = read(f, buf, sizeof(struct whod));
if (cc >= WHDRSIZE) {
+ /*
+ * Malloc new hs structs as needed.
+ * Stuff into linked list at its head.
+ */
+ hsp = (struct hs *) malloc(sizeof(struct hs));
+ hsp->hs_next = hs_head;
+ hs_head = hsp;
+ /* End malloc change. */
hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);
wd = (struct whod *)buf;
bcopy(buf, hsp->hs_wd, WHDRSIZE);
***************
*** 115,121
while (--we >= wd->wd_we)
if (aflg || we->we_idle < 3600)
hsp->hs_nusers++;
! nhosts++; hsp++;
}
}
(void) close(f);
--- 128,134 -----
while (--we >= wd->wd_we)
if (aflg || we->we_idle < 3600)
hsp->hs_nusers++;
! nhosts++;
}
}
(void) close(f);
***************
*** 120,127
}
(void) close(f);
}
! (void) time(&now);
! qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
if (nhosts == 0) {
printf("no hosts!?!\n");
exit(1);
--- 133,151 -----
}
(void) close(f);
}
! /*
! * Now malloc the pointer array and
! * copy the linked list to it.
! */
! hs = (struct hs **) malloc((unsigned)(nhosts*sizeof(struct hs *)));
! for (i = 0; i < nhosts; i++) {
! /* (*hs)[i] = hs_head; */
! *(hs+i) = hs_head;
! hs_head = hs_head->hs_next;
! }
! /* End malloc change. */
! (void) time((time_t *) &now);
! qsort((char *)hs, nhosts, sizeof (struct hs *), cmp);
if (nhosts == 0) {
printf("no hosts!?!\n");
exit(1);
***************
*** 127,133
exit(1);
}
for (i = 0; i < nhosts; i++) {
! hsp = &hs[i];
if (down(hsp)) {
printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
interval(now - hsp->hs_wd->wd_recvtime, "down"));
--- 151,157 -----
exit(1);
}
for (i = 0; i < nhosts; i++) {
! hsp = *(hs+i);
if (down(hsp)) {
printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
interval(now - hsp->hs_wd->wd_recvtime, "down"));
***************
*** 175,181
}
hscmp(h1, h2)
! struct hs *h1, *h2;
{
return (rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
--- 199,205 -----
}
hscmp(h1, h2)
! struct hs **h1, **h2;
{
return (rflg * strcmp((*h1)->hs_wd->wd_hostname,
***************
*** 178,184
struct hs *h1, *h2;
{
! return (rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
}
/*
--- 202,209 -----
struct hs **h1, **h2;
{
! return (rflg * strcmp((*h1)->hs_wd->wd_hostname,
! (*h2)->hs_wd->wd_hostname));
}
/*
***************
*** 185,191
* Compare according to load average.
*/
lcmp(h1, h2)
! struct hs *h1, *h2;
{
if (down(h1))
--- 210,216 -----
* Compare according to load average.
*/
lcmp(h1, h2)
! struct hs **h1, **h2;
{
if (down(*h1))
***************
*** 188,195
struct hs *h1, *h2;
{
! if (down(h1))
! if (down(h2))
return (tcmp(h1, h2));
else
return (rflg);
--- 213,220 -----
struct hs **h1, **h2;
{
! if (down(*h1))
! if (down(*h2))
return (tcmp(h1, h2));
else
return (rflg);
***************
*** 193,199
return (tcmp(h1, h2));
else
return (rflg);
! else if (down(h2))
return (-rflg);
else
return (rflg *
--- 218,224 -----
return (tcmp(h1, h2));
else
return (rflg);
! else if (down(*h2))
return (-rflg);
else
return (rflg *
***************
*** 197,203
return (-rflg);
else
return (rflg *
! (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]));
}
/*
--- 222,229 -----
return (-rflg);
else
return (rflg *
! ((*h2)->hs_wd->wd_loadav[0] -
! (*h1)->hs_wd->wd_loadav[0]));
}
/*
***************
*** 204,210
* Compare according to number of users.
*/
ucmp(h1, h2)
! struct hs *h1, *h2;
{
if (down(h1))
--- 230,236 -----
* Compare according to number of users.
*/
ucmp(h1, h2)
! struct hs **h1, **h2;
{
if (down(*h1))
***************
*** 207,214
struct hs *h1, *h2;
{
! if (down(h1))
! if (down(h2))
return (tcmp(h1, h2));
else
return (rflg);
--- 233,240 -----
struct hs **h1, **h2;
{
! if (down(*h1))
! if (down(*h2))
return (tcmp(h1, h2));
else
return (rflg);
***************
*** 212,218
return (tcmp(h1, h2));
else
return (rflg);
! else if (down(h2))
return (-rflg);
else
return (rflg * (h2->hs_nusers - h1->hs_nusers));
--- 238,244 -----
return (tcmp(h1, h2));
else
return (rflg);
! else if (down(*h2))
return (-rflg);
else
return (rflg * ((*h2)->hs_nusers - (*h1)->hs_nusers));
***************
*** 215,221
else if (down(h2))
return (-rflg);
else
! return (rflg * (h2->hs_nusers - h1->hs_nusers));
}
/*
--- 241,247 -----
else if (down(*h2))
return (-rflg);
else
! return (rflg * ((*h2)->hs_nusers - (*h1)->hs_nusers));
}
/*
***************
*** 222,228
* Compare according to uptime.
*/
tcmp(h1, h2)
! struct hs *h1, *h2;
{
long t1, t2;
--- 248,254 -----
* Compare according to uptime.
*/
tcmp(h1, h2)
! struct hs **h1, **h2;
{
return (rflg * (
***************
*** 224,230
tcmp(h1, h2)
struct hs *h1, *h2;
{
- long t1, t2;
return (rflg * (
(down(h2) ? h2->hs_wd->wd_recvtime - now
--- 250,255 -----
tcmp(h1, h2)
struct hs **h1, **h2;
{
return (rflg * (
(down(*h2) ? (*h2)->hs_wd->wd_recvtime - now
***************
*** 227,234
long t1, t2;
return (rflg * (
! (down(h2) ? h2->hs_wd->wd_recvtime - now
! : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
-
(down(h1) ? h1->hs_wd->wd_recvtime - now
: h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
--- 252,260 -----
{
return (rflg * (
! (down(*h2) ? (*h2)->hs_wd->wd_recvtime - now
! : (*h2)->hs_wd->wd_sendtime -
! (*h2)->hs_wd->wd_boottime)
-
(down(*h1) ? (*h1)->hs_wd->wd_recvtime - now
: (*h1)->hs_wd->wd_sendtime -
***************
*** 230,236
(down(h2) ? h2->hs_wd->wd_recvtime - now
: h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
-
! (down(h1) ? h1->hs_wd->wd_recvtime - now
! : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
));
}
--- 256,263 -----
: (*h2)->hs_wd->wd_sendtime -
(*h2)->hs_wd->wd_boottime)
-
! (down(*h1) ? (*h1)->hs_wd->wd_recvtime - now
! : (*h1)->hs_wd->wd_sendtime -
! (*h1)->hs_wd->wd_boottime)
));
}
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list