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