Bug /etc/ac (connect time errors)
webs at umcp-cs.UUCP
webs at umcp-cs.UUCP
Fri Nov 4 03:25:09 AEST 1983
Bug in /etc/ac. The index function for ut_line values is incorrect.
The following cases are not handled correctly:
1. ttyn If more than one ttyn are concurrently signed on their index
value COLLIDES as TSIZE-1.
2. ttyXX The ranges calculated for any combination of leading alpha
(upper or lower case) followed by anything generates collisions
e.g. 'Ax' give numbers 170 - 179 for A0 - A9,
187 - 222 for AA - AZ,
219 - 244 for Aa - Az.
'Bx' give numbers 180 - 189 for B0 - B9,
197 - 232 for BA - BZ,
229 - 254 for Bz - Bz.
Collisions occur within the 'Ax' group (AZ & Ad) &
across groups (B7 & AA).
I tested the index function change for two months worth of /usr/adm/wtmp data.
Results: Revised version allocated an additional 2102.44 hours.
(old 15098.77 hours, new: 17201.21 hours)
If your system only uses format ttynn where single number have leading zero
the current /etc/ac will work just fine. If you use alphas, or ttyn formats
the revision is for you.
There are other approaches to fix /etc/ac. If anyone inserts a table to
search for line values or some other method, I'd be interested in seeing your
code, maybe run a comparison?
The following fix will properly allocate index values for any case that uses
digits, non-blank alpha characters.
CAUTION: This case does NOT handle non-printable or printable special char-
acters, (e.g. * & ^ % $ # @ ! " ? / > < . , etc.)
1. change TSIZE: from #define TSIZE nnnn to: #define TSIZE 3900
2. replace line:
i = (ibuf.ut_line[3]-'0')*10 + (ibuf.ut_line[4]-'0');
with:
i = ttyindx(ibuf.ut_line[3], ibuf.ut_line[4]);
3. compile ttyindx.c as supplied below.
/*----------------------------------------------------------------*/
/* FUNCTION: ttyindx PURPOSE: Generate index for ttyXX values */
/* */
/* AUTHOR: Leigh S. Weber DATE: October 25, 1983 */
/* INSTITUTION: Computer Science Department, */
/* University of Maryland */
/* College Park, MD 20742 */
/* */
/* REASON: Fix hash function for /etc/ac connect time accounting*/
/* program. */
/*----------------------------------------------------------------*/
#include <stdio.h>
#include <ctype.h>
int base, factor, dig, i;
char c;
ttyindx(a, b)
int a, b;
{
/* generate numeric index from ttyXX values
*
* cases:
* 1. Single digit values: 0 - 9 inclusive
* 2. double digit values: 10 - 99 inclusive
* 3. Digit, char values: 100 - 619 inclusive
* 0A ==> 100 0B ==> 101 0a ==> 126 0z ==> 151
* 1A ==> 152 1B ==> 153 1a ==> 178 1z ==> 203
* ....
* 9A ==> 568 9B ==> 569 9a ==> 594 9z ==> 619
* 4. Alpha, Digit or Alpha
* Ordering by second char, lowest digit 0, highest z
* A0 ==> 620 A1 ==> 621 A ==> 630 AA ==> 631 Aa ==> 657 Az ==> 682
* B0 ==> 683 B1 ==> 684 B ==> 693 BA ==> 694 Ba ==> 720 Bz ==> 745
* ....
* Z0 ==>2195 Z1 ==>2196 Z ==>2205 ZA ==>2206 Za ==>2232 Zz ==>3895
* a0 ==>2258 a1 ==>2259 a ==>2268 aA ==>2269 aa ==>2295 az ==>2320
* ....
* z0 ==>3833 z1 ==>3834 z ==>3843 zA ==>3844 za ==>3870 zz ==>3895
*
* NOTE: Only digits and non-blank characters are valid symbols
* ALL other combinations will kick out
*
* NOTE 2: Although not natural, Alpha NULL is placed between Alpha 9
* and Alpha 'A'. Please make a note of it
*---------------------------------------------------------------*/
c = a;
if (isdigit(c))
{ dig = 1; /* set FIRST is DIGIT */
i= c - '0';} /* atoi conversion */
else
{ if (isalpha(c) && !isspace(c))
{ base = 620; /* alpha range group */
factor = 63; /* range */
dig = 0; /* first NOT a digit */
i = c- 'A' - (islower(c)?6:0);
/* account for non alpha */
}
else
{ dig = 5; /* set bad character */
goto BADTTY;
}
} /* end else of isdigit(c) */
c = b; /* 2nd char processing */
if (c != '\0') /* not end of string */
{ if (isalnum(c) && !isspace(c))
{ if(dig) /* first char digit */
{ factor = (isalpha(c)? 52 : 10);
base = (isalpha(c)? 89 : 0);
}
i = i * factor + base + c - '0'
+ (isupper(c)? -6: 0)
+ (islower(c)? -12: 0);
}
else
{ dig = 5;
goto BADTTY;
}
} /* end if-then c != '\0' */
else /* single character */
i = (dig? i: i*factor + base +10);
#ifdef DEBUG
if(dig != 5) printf(" %c%c==>%4d", a,b,i);
#endif DEBUG
return(i);
BADTTY: if(dig ==5){printf("\nbad tty %c%c\t", a, b); dig=0;}
} /* end of ttyindx , index generating function */
--
Name: Leigh Weber
UUCP: {seismo,allegra,brl-bmd}!umcp-cs!webs
CSNET: webs at umcp-cs
ARPA: webs.umcp-cs at CSNet-Relay
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list