|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T b
Length: 19977 (0x4e09)
Types: TextFile
Names: »badness.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Src/MTAconsole/badness.c«
/* badness.c: routines calculating and using "badness" */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Src/MTAconsole/RCS/badness.c,v 5.0 90/09/20 16:19:24 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Src/MTAconsole/RCS/badness.c,v 5.0 90/09/20 16:19:24 pp Exp Locker: pp $
*
* $Log: badness.c,v $
* Revision 5.0 90/09/20 16:19:24 pp
* rcsforce : 5.0 public release
*
*/
#include "console.h"
#define DEFAULT_TOTAL_NUMBER 10000.0
#define DEFAULT_TOTAL_VOLUME 1000000.0
struct tailor *tailors = NULL;
extern double atof();
extern char tailorfile[];
extern int max_vert_lines;
extern time_t currentTime;
extern char *compress();
double ub_total_number = DEFAULT_TOTAL_NUMBER,
ub_total_volume = DEFAULT_TOTAL_VOLUME;
extern Display *disp;
/* \f
*/
static double parse_ub(ub)
char *ub;
{
double pre;
char *end;
pre = strtod(ub, &end);
while (*end != '\0' && isspace(*end)) end++;
if (*end != '\0') {
switch (*end) {
case 'h':
pre *= 60.0;
break;
case 'd':
pre *= 24.0 * 60.0;
break;
case 'k':
pre *= 1000.0;
break;
case 'M':
pre *= 1000000.0;
break;
default:
break;
}
}
return pre;
}
static void add_total_ubs(entry)
char *entry;
{
char *ix, *str, *margv[20];
int i, margc;
char *buf = strdup(entry);
if ((ix = index(buf, ':')) == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("Incorrect console tailor file entry '%s'",buf));
free(buf);
return;
}
ix++;
compress(ix, ix);
margc = sstr2arg(ix, 20, margv, ",");
i = 0;
while (i < margc) {
if ((ix = index(margv[i], '<')) != NULL) {
*ix = '\0';
str = margv[i];
ix++;
while(*ix != '\0' && isspace(*ix)) ix++;
while(*str != '\0' && isspace(*str)) str++;
if (*ix == '\0' || *str == '\0')
return;
if (strncmp(str, "num", 3) == 0)
ub_total_number = parse_ub(ix);
else if (strncmp(str, "vol", 3) == 0)
ub_total_volume = parse_ub(ix);
else
PP_LOG(LLOG_EXCEPTIONS,
("Unknown console tailor variable '%s'",
str));
}
i++;
}
free(buf);
}
static struct tailor *tailor_new(entry)
char *entry;
{
struct tailor *ret;
char *ix, *str, *margv[20];
int i, margc;
char *buf = strdup(entry);
ret = (struct tailor *) calloc(1, sizeof(*ret));
if ((ix = index(buf, ':')) == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("Incorrect console tailor file entry '%s'",buf));
free((char *) ret);
free(buf);
return NULL;
}
*ix = '\0';
ret->key = strdup(buf);
ix++;
compress(ix, ix);
margc = sstr2arg(ix, 20, margv, ",");
i = 0;
while (i < margc) {
if ((ix = index(margv[i], '<')) != NULL) {
*ix = '\0';
str = margv[i];
ix++;
while (*ix != '\0' && isspace(*ix)) ix++;
while (*str != '\0' && isspace(*str)) str++;
if (*ix == '\0' || *str == '\0')
return NULL;
if (strncmp(str, "num", 3) == 0)
ret->ub_number = parse_ub(ix);
else if (strncmp(str, "vol", 3) == 0)
ret->ub_volume = parse_ub(ix);
else if (strncmp(str, "age", 3) == 0)
ret->ub_age = parse_ub(ix);
else if (strncmp(str, "las", 3) == 0)
ret->ub_last = parse_ub(ix);
else
PP_LOG(LLOG_EXCEPTIONS,
("Unknown console tailor variable '%s'",
str));
}
i++;
}
free(buf);
return ret;
}
static void tailor_add(plist, new)
struct tailor **plist, *new;
{
new->next = *plist;
*plist = new;
}
void tailor_free(list)
struct tailor *list;
{
if (list->key) free(list->key);
if (list->next) tailor_free(list->next);
free((char *) list);
}
/* \f
*/
struct tailor *find_tailor(name, list)
char *name;
struct tailor *list;
{
while (list != NULL
&& strcmp(list->key, name) != 0)
list = list->next;
return list;
}
/* \f
*/
#include "tai_defaults.inc"
extern char *myname;
static void tailor_add_one_default(plist, type, hardwired)
struct tailor **plist;
char *type,
*hardwired;
{
char *temp,
buf[BUFSIZ];
if (find_tailor(type, *plist) == NULL) {
if ((temp = XGetDefault(disp, myname, type)) != NULL) {
sprintf(buf, "%s:%s",type,temp);
tailor_add(plist, tailor_new(buf));
} else if ((temp = XGetDefault(disp,
APPLICATION_CLASS,
type)) != NULL) {
sprintf(buf, "%s:%s",type,temp);
tailor_add(plist, tailor_new(buf));
} else
tailor_add(plist,tailor_new(hardwired));
}
}
static void tailor_add_defaults(plist)
struct tailor **plist;
{
/* mts defaults */
tailor_add_one_default(plist, "mtsin-chan", default_mtsin_chan);
tailor_add_one_default(plist, "mtsout-chan", default_mtsout_chan);
tailor_add_one_default(plist, "mtsboth-chan", default_mtsboth_chan);
tailor_add_one_default(plist, "mtsin-mta", default_mtsin_mta);
tailor_add_one_default(plist, "mtsout-mta", default_mtsout_mta);
tailor_add_one_default(plist, "mtsboth-mta", default_mtsboth_mta);
tailor_add_one_default(plist, "mtsin-msg", default_mtsin_msg);
tailor_add_one_default(plist, "mtsout-msg", default_mtsout_msg);
tailor_add_one_default(plist, "mtsboth-msg", default_mtsboth_msg);
/* mta defaults */
tailor_add_one_default(plist, "mtain-chan", default_mtain_chan);
tailor_add_one_default(plist, "mtaout-chan", default_mtaout_chan);
tailor_add_one_default(plist, "mtaboth-chan", default_mtaboth_chan);
tailor_add_one_default(plist, "mtain-mta", default_mtain_mta);
tailor_add_one_default(plist, "mtaout-mta", default_mtaout_mta);
tailor_add_one_default(plist, "mtaboth-mta", default_mtaboth_mta);
tailor_add_one_default(plist, "mtain-msg", default_mtain_msg);
tailor_add_one_default(plist, "mtaout-msg", default_mtaout_msg);
tailor_add_one_default(plist, "mtaboth-msg", default_mtaboth_msg);
/* internal defaults */
tailor_add_one_default(plist, "internal-chan", default_internal_chan);
tailor_add_one_default(plist, "internal-mta", default_internal_mta);
tailor_add_one_default(plist, "internal-msg", default_internal_msg);
/* passive defaults */
tailor_add_one_default(plist, "passive-chan", default_passive_chan);
tailor_add_one_default(plist, "passive-mta", default_passive_mta);
tailor_add_one_default(plist, "passive-msg", default_passive_msg);
}
/* \f
*/
TaiInit()
{
FILE *fp = NULL;
char buf[BUFSIZ];
/* read in console tailor file */
if (tailorfile[0] != '\0') {
if ((fp = fopen(tailorfile, "r")) == NULL
&& tailorfile[0] != '/') {
char *home;
/* try relative to home directory */
if ((home = getenv("HOME")) != NULLCP) {
(void) sprintf(buf, "%s/%s",
home, tailorfile);
fp = fopen(buf, "r");
}
}
if (fp != NULL) {
while (fgets(buf, BUFSIZ, fp) != NULLCP) {
if (strncmp(buf,"totals", strlen("totals")) == 0)
add_total_ubs(buf);
else
tailor_add(&tailors, tailor_new(buf));
}
fclose(fp);
}
}
tailor_add_defaults(&tailors);
}
/* \f
*/
add_tailor_to_chan(chan)
struct chan_struct *chan;
{
char buf[BUFSIZ];
sprintf(buf, "%s-chan", chan->channelname);
if ((chan->tai = find_tailor(buf, tailors)) == NULL) {
/* no explicit try defaults */
char *type = NULL,
*dir = NULL;
switch (chan->chantype) {
case int_Qmgr_chantype_mta:
type = strdup("mta");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_mts:
type = strdup("mts");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_internal:
type = strdup("internal");
break;
case int_Qmgr_chantype_passive:
default:
type = strdup("passive");
break;
}
sprintf(buf, "%s%s-chan",
type,
(dir == NULL) ? "" : dir);
if (type) free(type);
if (dir) free(dir);
chan->tai = find_tailor(buf, tailors);
}
}
add_tailor_to_mta(chan, mta)
struct chan_struct *chan;
struct mta_struct *mta;
{
char buf[BUFSIZ];
sprintf(buf, "%s-mta", chan->channelname);
if ((mta->tai = find_tailor(buf, tailors)) == NULL) {
/* no explicit try defaults */
char *type = NULL,
*dir = NULL;
switch (chan->chantype) {
case int_Qmgr_chantype_mta:
type = strdup("mta");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_mts:
type = strdup("mts");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_internal:
type = strdup("internal");
break;
case int_Qmgr_chantype_passive:
default:
type = strdup("passive");
break;
}
sprintf(buf, "%s%s-mta",
type,
(dir == NULL) ? "" : dir);
if (type) free(type);
if (dir) free(dir);
mta->tai = find_tailor(buf, tailors);
}
}
add_tailor_to_msg(chan, msg)
struct chan_struct *chan;
struct msg_struct *msg;
{
char buf[BUFSIZ];
sprintf(buf, "%s-msg", chan->channelname);
if ((msg->tai = find_tailor(buf, tailors)) == NULL) {
/* no explicit try defaults */
char *type = NULL,
*dir = NULL;
switch (chan->chantype) {
case int_Qmgr_chantype_mta:
type = strdup("mta");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_mts:
type = strdup("mts");
if (chan->outbound > 0 && chan->inbound > 0)
dir = strdup("both");
else if (chan->inbound > 0)
dir = strdup("in");
else if (chan->outbound > 0)
dir = strdup("out");
break;
case int_Qmgr_chantype_internal:
type = strdup("internal");
break;
case int_Qmgr_chantype_passive:
default:
type = strdup("passive");
break;
}
sprintf(buf, "%s%s-msg",
type,
(dir == NULL) ? "" : dir);
if (type) free(type);
if (dir) free(dir);
msg->tai = find_tailor(buf, tailors);
}
}
/* \f
*/
int volBadness(vol)
int vol;
{
int retval = 0;
if (ub_total_volume != 0.0)
retval = (int) (vol*100/ub_total_volume);
if (vol != 0 && retval == 0)
retval = 1;
return retval;
}
int numBadness(num)
int num;
{
int retval = 0;
if (ub_total_number != 0.0)
retval = (int) (num*100/ub_total_number);
if (num != 0 && retval == 0)
return 1;
return retval;
}
int chanBadness(chan)
struct chan_struct *chan;
{
double average_db = 0.0,
age,
last;
int average = 0,
noFactors = 0;
register struct tailor *tai = chan->tai;
if (tai == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("No tailoring for channel '%s'", chan->channelname));
return 0;
}
if (chan->inbound == 0
&& chan->numberMessages == 0
&& chan->numberReports == 0)
return 0;
if (tai->ub_number != 0.0) {
if ((chan->numberMessages + chan->numberReports) >= tai->ub_number)
return max_bad_channel;
average_db += ((chan->numberMessages+chan->numberReports) * 100)/ tai->ub_number;
noFactors++;
}
if (tai->ub_volume != 0.0) {
if (chan->volumeMessages >= tai->ub_volume)
return max_bad_channel;
average_db += (chan->volumeMessages * 100)/tai->ub_volume;
noFactors++;
}
if (tai->ub_age != 0.0) {
if (chan->oldestMessage != 0 &&
(chan->numberMessages != 0 || chan->numberReports != 0))
age = (currentTime-chan->oldestMessage) / 60.0;
else
age = 0.0;
if (age >= tai->ub_age)
return max_bad_channel;
average_db += (age * 100)/tai->ub_age;
noFactors++;
}
if (tai->ub_last != 0.0) {
if (chan->status->lastSuccess != 0.0)
last = (currentTime - chan->status->lastSuccess)/60.0;
else
last = 0.0;
if (last >= tai->ub_last)
return max_bad_channel;
if (last >= tai->ub_last/2) {
average_db += (last * 100)/tai->ub_last;
noFactors++;
}
}
/* scale up those that don't use all factors */
if (noFactors != 0)
average = (int) (average_db * max_bad_channel / (noFactors * 100));
if (average == 0 && average_db != 0.0)
return 1;
return average;
}
/* \f
*/
int mtaBadness(mta)
struct mta_struct *mta;
{
double average_db = 0.0,
age,
last;
int average = 0,
noFactors = 0;
register struct tailor *tai = mta->tai;
if (tai == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("No tailoring for mta '%s'", mta->mta));
return 0;
}
if (mta->numberMessages == 0 && mta->numberReports == 0)
return 0;
if (tai->ub_number != 0.0) {
if (mta->numberMessages+mta->numberReports >= tai->ub_number)
return max_bad_mta;
average_db += ((mta->numberMessages+mta->numberReports) * 100)/ tai->ub_number;
noFactors++;
}
if (tai->ub_volume != 0.0) {
if (mta->volumeMessages >= tai->ub_volume)
return max_bad_mta;
average_db += (mta->volumeMessages * 100)/tai->ub_volume;
noFactors++;
}
if (tai->ub_age != 0.0) {
if (mta->oldestMessage != 0
&& (mta->numberMessages != 0 || mta->numberReports != 0))
age = (currentTime-mta->oldestMessage) / 60.0;
else
age = 0;
if (age >= tai->ub_age)
return max_bad_mta;
average_db += (age * 100)/tai->ub_age;
noFactors++;
}
if (tai->ub_last != 0.0) {
if (mta->status->lastSuccess != 0)
last = (currentTime - mta->status->lastSuccess)/60.0;
else
last = 0;
if (last >= tai->ub_last)
return max_bad_mta;
if (last >= tai->ub_last/2) {
average_db += (last * 100)/tai->ub_last;
noFactors++;
}
}
/* scale up those that don't use all factors */
if (noFactors != 0)
average = (int) (average_db * max_bad_mta / (noFactors * 100));
if (average == 0 && average_db != 0.0)
return 1;
return average;
}
/* \f
*/
int msgBadness(msg)
struct msg_struct *msg;
{
double average_db = 0.0,
age;
int average = 0,
noFactors = 0;
register struct tailor *tai = msg->tai;
if (tai == NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("No tailoring for msg '%s'", msg->msginfo->queueid));
return 0;
}
if (msg->msginfo->expiryTime != 0
&& (currentTime - msg->msginfo->expiryTime) >= 0)
/* expired so max_bad_msg ?? */
return max_bad_msg;
if (tai->ub_age != 0.0) {
age = (currentTime-msg->msginfo->age) / 60.0;
if (age >= tai->ub_age)
return max_bad_msg;
average_db += (age * 100)/tai->ub_age;
noFactors++;
}
if (tai->ub_volume != 0.0) {
if (msg->msginfo->size > tai->ub_volume)
return max_bad_msg;
average_db += (msg->msginfo->size * 100) / tai->ub_volume;
noFactors++;
}
/* scale up those that don't use all factors */
if (noFactors != 0)
average = (int) (average_db * max_bad_msg / (noFactors * 100));
if (average == 0 && average_db != 0.0)
return 1;
return average;
}
/* \f
*/
/* colour routines */
extern struct color_item *colors;
extern XColor white,
black;
extern Pixel fg, bg;
extern int num_colors;
unsigned long volcolourOf(vol)
int vol;
{
int bad,
ix;
bad = volBadness(vol);
if (bad == 0)
return bg;
else {
ix = bad*num_colors/ub_total_volume;
if (ix >= num_colors)
ix = num_colors-1;
return colors[ix].colour.pixel;
}
}
unsigned long numcolourOf(num)
int num;
{
int bad,
ix;
bad = numBadness(num);
if (bad == 0)
return bg;
else {
ix = bad*num_colors/ub_total_number;
if (ix >= num_colors)
ix = num_colors-1;
return colors[ix].colour.pixel;
}
}
unsigned long chancolourOf (chan)
struct chan_struct *chan;
{
int bad,
ix;
/* find nearest index to chanBadness(chan)'s value */
/* always round up at moment */
bad = chanBadness(chan);
if (bad == 0)
/* output white border colour */
return bg;
else {
ix = bad*num_colors/max_bad_channel;
if (ix >= num_colors)
ix = num_colors-1;
return colors[ix].colour.pixel;
}
}
unsigned long mtacolourOf (mta)
struct mta_struct *mta;
{
int bad,
ix;
/* find nearest index to mtaBadness(mta)'s value */
/* always round up at moment */
bad = mtaBadness(mta);
if (bad == 0)
/* output white border colour */
return bg;
else {
ix = bad*num_colors/max_bad_mta;
if (ix >= num_colors)
ix = num_colors-1;
return colors[ix].colour.pixel;
}
}
unsigned long msgcolourOf (msg)
struct msg_struct *msg;
{
int bad,
ix;
/* find nearest index to msgBadness(msg)'s value */
/* always round up at moment */
bad = msgBadness(msg);
if (bad == 0)
return bg;
else {
ix = bad*num_colors/max_bad_msg;
if (ix >= num_colors)
ix = num_colors-1;
return colors[ix].colour.pixel;
}
}
/* \f
*/
/* border routines */
extern int max_chan_border,
max_mta_border,
max_msg_border;
int chanborderOf(chan)
struct chan_struct *chan;
{
#ifdef R4
int bad,
wid;
bad = chanBadness(chan);
if (bad == 0)
return 1;
else {
wid = max_chan_border*bad/max_bad_channel + 1;
if (wid > max_chan_border)
wid = max_chan_border;
return wid;
}
#else
return 2;
#endif
}
int mtaborderOf(mta)
struct mta_struct *mta;
{
#ifdef R4
int bad,
wid;
bad = mtaBadness(mta);
if (bad == 0)
return 1;
else {
wid = max_mta_border*bad/max_bad_mta + 1;
if (wid > max_mta_border)
wid = max_mta_border;
return wid;
}
#else
return 2;
#endif
}
int msgborderOf(msg)
struct msg_struct *msg;
{
#ifdef R4
int bad,
wid;
bad = msgBadness(msg);
if (bad == 0)
return 1;
else {
wid = max_msg_border*bad/max_bad_msg + 1;
if (wid > max_msg_border)
wid = max_msg_border;
return wid;
}
#else
return 2;
#endif
}
/* \f
*/
/* ordering routines */
extern int num_channels;
extern struct chan_struct **ordered_list;
static int channel_compare(one, two)
struct chan_struct **one,
**two;
/* return -1 if one worse state then two */
{
int onebad,
twobad;
onebad = chanBadness((*one));
twobad = chanBadness((*two));
if (onebad < twobad)
return 1;
else if (onebad > twobad)
return -1;
else
return 0;
}
order_display_channels()
/* order display_list */
{
qsort((char *) &(ordered_list[0]),num_channels,
sizeof(ordered_list[0]),channel_compare);
}
static int mta_compare (one, two)
struct mta_struct **one,
**two;
/* returns -1 if ione in worse state than two */
{
int onebad,
twobad;
onebad = mtaBadness((*one));
twobad = mtaBadness((*two));
if (onebad < twobad)
return 1;
else if (onebad > twobad)
return -1;
else
return 0;
}
order_mtas(plist,num)
struct mta_struct ***plist;
int num;
{
struct mta_struct **temp = *plist;
qsort((char *)&(temp[0]),num,sizeof(temp[0]),mta_compare);
}
extern int number_msgs;
extern struct msg_struct **global_msg_list;
static int msg_compare (one, two)
struct msg_struct **one,
**two;
/* returns -1 if ione in worse state than two */
{
int onebad,
twobad;
onebad = msgBadness((*one));
twobad = msgBadness((*two));
if (onebad < twobad)
return 1;
else if (onebad > twobad)
return -1;
else
return 0;
}
order_msgs()
{
qsort((char *) &(global_msg_list[0]),number_msgs,
sizeof(global_msg_list[0]),msg_compare);
}
/* \f
*/
int NumVertLines(chan)
struct chan_struct *chan;
{
int ret = 1 + (max_vert_lines * chanBadness(chan))/max_bad_channel;
return ret;
}
extern XFontStruct *disabledFont,
*activeFont,
*normalFont;
XFontStruct *chanFont(chan)
struct chan_struct *chan;
{
if (chan == NULL)
return normalFont;
if (chan->status->enabled == FALSE)
return disabledFont;
else if (chan->numberActiveProcesses > 0)
return activeFont;
else
return normalFont;
}
XFontStruct *mtaFont(mta)
struct mta_struct *mta;
{
if (mta == NULL)
return normalFont;
if (mta->status->enabled == FALSE)
return disabledFont;
else if (mta -> active)
return activeFont;
else
return normalFont;
}
XFontStruct *msgFont(msg)
struct msg_struct *msg;
{
struct recip *ix;
if (msg == NULL)
return normalFont;
ix = msg->reciplist;
while (ix != NULL) {
if (ix -> status -> enabled == FALSE)
return disabledFont;
ix = ix -> next;
}
return normalFont;
}