|
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 c
Length: 15998 (0x3e7e) Types: TextFile Names: »ckchan.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Tools/ckchan/ckchan.c«
/* ckchan.c: standalone channel checker */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/ckchan/RCS/ckchan.c,v 5.0 90/09/20 16:24:38 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Tools/ckchan/RCS/ckchan.c,v 5.0 90/09/20 16:24:38 pp Exp Locker: pp $ * * $Log: ckchan.c,v $ * Revision 5.0 90/09/20 16:24:38 pp * rcsforce : 5.0 public release * */ #include "util.h" #include <pwd.h> #include <isode/usr.dirent.h> #include <sys/stat.h> #include <signal.h> #include "q.h" #include "retcode.h" #include "prm.h" static void rd_end (); static int my_rd_msg (); extern void getfpath (); extern CHAN *ch_nm2struct(); #define TABSIZE 6 static int isMsgFile(); static void build_chanlist(); static struct my_chan_struct *get_chan(); static struct my_chan_struct *add_chan(); static void add_entry(); static void order_mtas(); static void add_msg(); static void add_drmsg(); static void add_to_chanlist(); static void print_chanlist(); static void print_chan(); static void print_mta(); static void print_msg(); static void print_drmta(); static void print_drmsg(); static LIST_RCHAN *getnthchannel(); #define TIMETROUBLE 24 * 60 * 60 time_t timetrouble = TIMETROUBLE; #define noMTA "NO MTA!" typedef struct recip_struct { char *recip; int status; struct recip_struct *recip_next; } Recip_struct; typedef struct msg_struct { time_t age; char *msg; Q_struct *que; struct recip_struct *recips; struct msg_struct *msg_next; } Msg_struct; typedef struct mta_struct { char *mta; int nmsgs; time_t oldestmsg; struct msg_struct *msgs; struct mta_struct *mta_next; } Mta_struct; typedef struct my_chan_struct { char *name; struct mta_struct *mtas; struct mta_struct *drmtas; struct my_chan_struct *chan_next; } My_chan_struct; int all, verbose; struct my_chan_struct *chan_list = NULL; main (argc, argv) int argc; char **argv; { struct stat statbuf; struct prm_vars prm; Q_struct *que; ADDR *sender = NULL; ADDR *recips = NULL; int rcount; int opt, flags; extern int optind; extern char *optarg; char real_aquedir[FILNSIZE]; struct dirent **namelist = NULL, **ix; extern char *quedfldir; extern char *aquedir, *postmaster; int num, i; all = FALSE; flags = 0; verbose = FALSE; (void) signal(SIGPIPE, SIG_DFL); while ((opt = getopt(argc, argv, "v")) != EOF) { switch (opt) { case 'v': /* verbose output */ verbose = TRUE; flags++; break; default: printf("usage : %s [-v] [ chan ...]\n",argv[0]); exit(1); } } sys_init(argv[0]); argv += flags + 1; if (*argv == NULL) all=TRUE; else build_chanlist(argv); /* get addr directory name */ getfpath (quedfldir, aquedir, real_aquedir); if (stat(real_aquedir, &statbuf) != OK) { printf("Unable to find spool area\nPlease inform %s\n", postmaster); exit(1); } printf("Please wait while information is processed..."); fflush(stdout); num = _scandir(real_aquedir, &namelist, isMsgFile, NULL); i = 0; ix = namelist; while (ix != NULL && *ix != NULL && i < num) { /* printf("processing %s\n", (*ix) -> d_name);*/ sender = NULL; recips = NULL; i++; prm_init (&prm); que = (Q_struct *) calloc(1, sizeof(*que)); if (rp_isbad(my_rd_msg((*ix)->d_name,&prm,que,&sender,&recips,&rcount))) { rd_end(); printf("Bad message %s : rd_msg fails\n",(*ix)->d_name); } else { rd_end(); add_to_chanlist((*ix)->d_name,que); } /* q_free (&que);*/ ix++; } printf("done\n"); print_chanlist(); if (namelist) free((char *) namelist); /* free_chanlist();*/ } static char *time_t2str(in) time_t in; { char buf[BUFSIZ]; time_t result; buf[0] = '\0'; if (in < 0) return strdup("still in the womb"); if ((result = in / (60 * 60 * 24)) != 0) { sprintf(buf, "%d days",result); in = in % (60 * 60 * 24); } if ((result = in / (60 * 60)) != 0) { sprintf(buf, (buf[0] == '\0') ? "%s%d hrs" : "%s %d hrs", buf, result); in = in % (60 * 60); } if ((result = in / 60) != 0) { sprintf(buf, (buf[0] == '\0') ? "%s%d mins" : "%s %d mins", buf, result); in = in % 60; } if (buf[0] == '\0' && in != 0) sprintf(buf, "%d secs", in); if (buf[0] == '\0') sprintf(buf, "just born"); return strdup(buf); } static char *time_t2RFC(in) time_t in; { char buf[BUFSIZ], *str; time_t curr, delta; curr = time(0); delta = curr - in; str = time_t2str(delta); sprintf(buf,"%s%s", str, (delta > timetrouble) ? " *****" : ""); free(str); return strdup(buf); } static int isMsgFile (entry) struct dirent *entry; { if (strncmp(entry->d_name, "msg.", 4) == 0) return 1; else return 0; } static void build_chanlist(chans) char **chans; { struct my_chan_struct *temp; CHAN *chan; char **ix = chans; while (*ix != NULL) { if (lexequ(*ix, "ALL") == 0) all = TRUE; else if ((chan = ch_nm2struct(*ix)) == NULLCHAN) printf("unknown channel '%s'\n",*ix); else temp = add_chan(chan); ix++; } } static struct mta_struct *get_mta(list, mta) struct mta_struct *list; char *mta; { struct mta_struct *ix = list; while (ix != NULL && (strcmp(ix->mta,mta) != 0)) ix = ix -> mta_next; return ix; } static struct msg_struct *get_msg(list, key) struct msg_struct *list; char *key; { struct msg_struct *ix = list; while (ix != NULL && (strcmp(ix->msg,key) != 0)) ix = ix -> msg_next; return ix; } static struct my_chan_struct *get_chan(chan) CHAN *chan; { struct my_chan_struct *ix = chan_list; while ((ix != NULL) && (strcmp(ix->name,chan->ch_name) != 0)) ix = ix->chan_next; return ix; } static struct my_chan_struct *add_chan(chan) CHAN *chan; { struct my_chan_struct *temp = (struct my_chan_struct *) calloc(1, sizeof(*temp)); temp->name = strdup(chan->ch_name); temp->chan_next = chan_list; chan_list = temp; return chan_list; } static void add_recip(plist, adr) struct recip_struct **plist; ADDR *adr; { struct recip_struct *ret = (struct recip_struct *) calloc(1, sizeof(*ret)); ret -> recip = adr -> ad_value; ret -> status = adr -> ad_status; ret -> recip_next = *plist; *plist = ret; } static struct msg_struct *new_msg(msg, que, recip) char *msg; Q_struct *que; ADDR *recip; { struct msg_struct *ret = (struct msg_struct *) calloc(1, sizeof(*ret)); ret -> age = utc2time_t(que -> queuetime); ret -> msg = msg; ret -> que = que; add_recip(&ret -> recips, recip); return ret; } static void add_msg(plist, msg) struct msg_struct **plist, *msg; { struct msg_struct *ix = *plist; if (*plist == NULL || (*plist) -> age > msg -> age) { msg -> msg_next = *plist; *plist = msg; } else { while ( ix -> msg_next != NULL && ix -> msg_next -> age <= msg -> age) ix = ix -> msg_next; msg -> msg_next = ix -> msg_next; ix -> msg_next = msg; } } #define NEW 0 #define OLD 1 static int update_msg(plist,msg,que,recip) struct msg_struct **plist; char *msg; Q_struct *que; ADDR *recip; { struct msg_struct *temp; if ((temp = get_msg(*plist,msg)) == NULL) { temp = new_msg(msg, que, recip); add_msg(plist, temp); return NEW; } else { add_recip(&temp->recips, recip); return OLD; } } static void update_mta(mta, msg, que, recip) struct mta_struct *mta; char *msg; Q_struct *que; ADDR *recip; { time_t qtime; qtime = utc2time_t(que->queuetime); if (qtime < mta -> oldestmsg) mta -> oldestmsg = qtime; if (update_msg(&mta->msgs, msg, que, recip) == NEW) mta->nmsgs++; } static void new_mta(plist, msg, que, recip, inmta) struct mta_struct **plist; char *msg; Q_struct *que; ADDR *recip; char *inmta; { struct mta_struct *temp = (struct mta_struct *) calloc(1, sizeof(*temp)); if (recip ->ad_outchan && recip->ad_outchan->li_mta != NULLCP) temp -> mta = strdup(recip -> ad_outchan -> li_mta); else if (inmta != NULL) temp -> mta = strdup(inmta); else temp->mta = strdup(noMTA); temp -> nmsgs = 1; temp -> oldestmsg = utc2time_t(que -> queuetime); update_msg(&temp->msgs, msg, que, recip); temp -> mta_next = *plist; *plist = temp; } static void add_mta(msg,que,recip,chan) char *msg; Q_struct *que; ADDR *recip; CHAN *chan; { struct my_chan_struct *temp; struct mta_struct *mta; char *chmta; if ((temp = get_chan(chan)) == NULL && all == TRUE) temp = add_chan(chan); if (temp == NULL) /* not interested in this channel */ return; if (recip->ad_outchan && recip->ad_outchan->li_mta) chmta = recip->ad_outchan->li_mta; else chmta = noMTA; if ((mta = get_mta(temp -> mtas,chmta)) == NULL) new_mta(&(temp -> mtas), msg, que, recip, chmta); else update_mta(mta,msg,que,recip); } static void add_drmta(msg,que,sender,chan) char *msg; Q_struct *que; ADDR *sender; LIST_RCHAN *chan; { struct my_chan_struct *temp; struct mta_struct *mta; char *chmta; if (chan->li_chan == NULL || chan->li_chan->ch_name == NULL) { PP_OPER(NULL, ("Outchan for DR not set (sorry can't be of more help !)")); return; } if ((temp = get_chan(chan->li_chan)) == NULL && all == TRUE) temp = add_chan(chan->li_chan); if (temp == NULL) /* not interested in this channel */ return; if (sender->ad_outchan && sender->ad_outchan->li_mta) chmta = sender->ad_outchan->li_mta; else if (chan->li_mta) chmta = chan->li_mta; else chmta = noMTA; if ((mta = get_mta(temp -> drmtas, chmta)) == NULL) new_mta(&(temp -> drmtas), msg, que, sender, chmta); else update_mta(mta,msg,que,sender); } static void add_to_chanlist(msg,que) char *msg; Q_struct *que; { ADDR *ix = que->Raddress; LIST_RCHAN *chan, *chanix; while (ix != NULL) { if (ix -> ad_status == AD_STAT_DRWRITTEN || ix -> ad_status == AD_STAT_DRREQUIRED) { chanix = que->Oaddress->ad_outchan; while (chanix != NULL) { add_drmta(msg, que, que->Oaddress, chanix); chanix = chanix->li_next; } } else if (ix -> ad_status != AD_STAT_DONE) { /* must be on a channel */ /* check reformaters */ if ((chan = getnthchannel(ix->ad_fmtchan, ix -> ad_rcnt)) != NULL) /* still needs reformating */ add_mta(msg,que,ix,chan->li_chan); else { /* on outbound channel */ chanix = ix->ad_outchan; while (chanix != NULL) { add_mta(msg,que,ix,chanix->li_chan); chanix = chanix->li_next; } } } ix = ix->ad_next; } } static void print_chanlist() { struct my_chan_struct *ix = chan_list; while (ix != NULL) { print_chan(ix); ix = ix -> chan_next; } } static void print_chan(chanptr) struct my_chan_struct *chanptr; { struct mta_struct *ix; printf("%s\n",chanptr->name); order_mtas(&(chanptr->mtas)); if ((ix = chanptr -> mtas) != NULL) printf("%*smessages\n",TABSIZE/2,""); while (ix != NULL) { print_mta(ix); ix = ix -> mta_next; } order_mtas(&(chanptr->drmtas)); if ((ix = chanptr -> drmtas) != NULL) printf("%*sDRs\n",TABSIZE/2,""); while (ix != NULL) { print_drmta(ix); ix = ix -> mta_next; } } static void print_mta(mta) struct mta_struct *mta; { struct msg_struct *ix; char *timestring; if (verbose == TRUE) { printf("%*s%s\n",TABSIZE,"",mta->mta); ix = mta->msgs; while (ix != NULL) { print_msg(ix); ix = ix -> msg_next; } } else { timestring = time_t2RFC(mta->oldestmsg); printf("%*s%-25s %d%*s%s\n", TABSIZE,"", mta -> mta, mta -> nmsgs, TABSIZE,"", timestring); free(timestring); } } static void print_drmta(mta) struct mta_struct *mta; { struct msg_struct *ix; char *timestring; if (verbose == TRUE) { printf("%*s%s\n",TABSIZE,"",mta->mta); ix = mta->msgs; while (ix != NULL) { print_drmsg(ix); ix = ix -> msg_next; } } else { timestring = time_t2RFC(mta->oldestmsg); printf("%*s%-25s %d%*s%s\n", TABSIZE,"", mta -> mta, mta -> nmsgs, TABSIZE,"", timestring); free(timestring); } } char *status_str[] = { "unknown", "pend", "dr req", "dr written", "done" }; static void print_msg(msg) struct msg_struct *msg; { char *timestring = time_t2RFC(msg->age); struct recip_struct *ix = msg -> recips; printf("%*s%-25s %s\n", 2*TABSIZE,"", msg->msg, timestring); printf("%*sfrom %-30s", 3*TABSIZE,"", msg->que->Oaddress->ad_value); if (ix == NULL) printf (" %s\n", status_str[AD_STAT_DRWRITTEN]); else printf("\n"); while (ix != NULL) { printf("%*sto %-30s %s\n", 3*TABSIZE,"", ix -> recip, status_str[ix -> status]); ix = ix -> recip_next; } free(timestring); } static void print_drmsg(msg) struct msg_struct *msg; { char *timestring = time_t2RFC(msg->age); struct recip_struct *ix = msg -> recips; printf("%*s%-25s %s\n", 2*TABSIZE,"", msg->msg, timestring); printf("%*sto %-30s\n", 3*TABSIZE,"", msg->que->Oaddress->ad_value); while (ix != NULL) { printf("%*sfrom recip %-30s\n", 3*TABSIZE,"", ix -> recip); ix = ix -> recip_next; } free(timestring); } static LIST_RCHAN *getnthchannel(chans,num) LIST_RCHAN *chans; int num; { LIST_RCHAN *ix = chans; int icount = 0; while ((ix != NULL) && (icount++ < num)) ix = ix->li_next; return ix; } static void insert_mta(plist, mta) struct mta_struct **plist, *mta; { struct mta_struct *ix = *plist; if (*plist == NULL || (*plist) -> oldestmsg > mta -> oldestmsg) { mta -> mta_next = *plist; *plist = mta; } else { while ( ix -> mta_next != NULL && ix -> mta_next -> oldestmsg <= mta -> oldestmsg) ix = ix -> mta_next; mta -> mta_next = ix -> mta_next; ix -> mta_next = mta; } } static void order_mtas(plist) struct mta_struct **plist; { struct mta_struct *new = NULL, *head = *plist, *tail; while (head != NULL) { tail = head -> mta_next; insert_mta(&new, head); head = tail; } *plist = new; } static dummy() { realloc (); } extern int errno; extern char *aquedir, *no2txt3(); static FILE *msg_fp; static char msgname[FILNSIZE]; int ad_count; static int my_rd_msg (file, prm, que, sender, recip, rcount) char *file; struct prm_vars *prm; Q_struct *que; ADDR **sender; ADDR **recip; int *rcount; { int retval; char real_aquedir[FILNSIZE]; extern char *quedfldir; PP_DBG (("Lib/io/rd_msg(%s%s)", aquedir, file)); getfpath (quedfldir, aquedir, real_aquedir); getfpath (real_aquedir, file, msgname); if ((msg_fp = fopen (msgname, "r")) == NULLFILE) { PP_SLOG (LLOG_EXCEPTIONS, msgname, ("Lib/io/rd_msg flckopen error")); return (RP_FOPN); } if (rp_isbad (retval = rd_prm (prm, msg_fp))) { PP_LOG (LLOG_EXCEPTIONS, ("Lib/io/rd_msg/rd_prm err: '%s'", msgname)); rd_end(); return (retval); } if (rp_isbad (retval = rd_q (que, msg_fp))) { PP_LOG (LLOG_EXCEPTIONS, ("Lib/io/rd_msg/rd_q err: '%s'", msgname)); rd_end(); return (retval); } if (rp_isbad (retval = rd_adr (msg_fp, TRUE, sender))) { PP_LOG (LLOG_EXCEPTIONS, ("Lib/io/rd_msg/rd_adr sender err: %s %s", rp_valstr (retval), msgname)); rd_end(); return (retval); } ad_count = 0; if (rp_isbad (retval = rd_adr (msg_fp, FALSE, recip))) { PP_LOG (LLOG_EXCEPTIONS, ("Lib/io/rd_msg/rd_adr recip err: %s %s", rp_valstr(retval), msgname)); rd_end(); return (retval); } que -> Oaddress = *sender; que -> Raddress = *recip; *rcount = ad_count; return (RP_OK); } static void rd_end () { PP_DBG (("Lib/io/rd_end()")); if (msg_fp) (void) flckclose (msg_fp); msg_fp = NULLFILE; }