|
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; }