webs@umcp-cs.UUCP (11/03/83)
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@umcp-cs ARPA: webs.umcp-cs@CSNet-Relay