home *** CD-ROM | disk | FTP | other *** search
- #include "util.h"
- #include "mmdf.h"
- #include "ch.h"
- #include "adr_queue.h"
- #include "msg.h"
- /*
- * MULTI-CHANNEL MEMO DISTRIBUTION FACILITY (MMDF)
- *
- *
- * Copyright (C) 1979,1980,1981 University of Delaware
- *
- * Department of Electrical Engineering
- * University of Delaware
- * Newark, Delaware 19711
- *
- * Phone: (302) 738-1163
- *
- *
- * This program module was developed as part of the University
- * of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
- *
- * Acquisition, use, and distribution of this module and its listings
- * are subject restricted to the terms of a license agreement.
- * Documents describing systems using this module must cite its source.
- *
- * The above statements must be retained with all copies of this
- * program and may not be removed without the consent of the
- * University of Delaware.
- *
- *
- * version -1 David H. Crocker March 1979
- * version 0 David H. Crocker April 1980
- * version v7 David H. Crocker May 1981
- * version 1 David H. Crocker October 1981
- *
- */
-
- /* Jun 80 D. Crocker RP_USER -> RP_NDEL on no valid users
- * Nov 80 D. Crocker Reduce verbosity if more than 12 addrs.
- * Jun 82 D. Crocker null chan -> source spec
- * Jul 82 D. Crocker qf_ -> mq_
- */
- extern struct ll_struct *logptr;
- extern Chan **ch_tbsrch; /* for sorting addrs by channel */
- extern char *strdup ();
- extern char *mgt_return; /* sender's return address */
- extern short tracing;
- extern int lnk_listsize;
-
- LOCFUN lnk_insrt(), lnk_cmpr();
-
- struct lnk_struct
- {
- struct lnk_struct *lnk_nxt; /* where the next entry is */
- struct ch_struct *lnk_ch; /* what delivery pgm to run */
- short lnk_chpri; /* "priority" of chan in ch_tbsrch[] */
- char *lnk_host; /* host part of address */
- char *lnk_mbox; /* mailbox part of address */
- };
-
- short lnk_nadrs; /* current number of addresses */
- short lnk_nentries; /* current number of entries in list */
-
- /* *************** (lnk_) ADDRESS LINKED-LIST PRIMITIVES *********** */
-
- LOCVAR struct lnk_struct lnk_strt;
- /* 1st address in list */
-
- lnk_adinfo (thechan, hostr, mbox) /* given constituents, add to list */
- Chan *thechan; /* internal chan name/code */
- char *hostr, /* official name of host */
- *mbox; /* name of mailbox */
- {
- extern char *ut_alloc ();
- register struct lnk_struct *tstadr;
- register short ch_ind;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "lnk_adinfo ()");
- #endif
-
- /*NOSTRICT*/
- tstadr = (struct lnk_struct *) ut_alloc (sizeof (struct lnk_struct));
- if ((tstadr -> lnk_ch = thechan) == (Chan *) 0)
- ch_ind = -1; /* really a source specification */
- else
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "lnk_adinfo (%s(->%s), %s, %s)",
- thechan -> ch_name, thechan -> ch_queue,
- hostr, mbox);
- #endif
- if (tracing) {
- printf("queueing for %s: via '%s': '%s'\n",
- thechan -> ch_name, hostr, mbox);
- fflush(stdout);
- }
- for (ch_ind = 0; ch_tbsrch[ch_ind] != 0 &&
- ch_tbsrch[ch_ind] != thechan; ch_ind++);
- /* chan's "priority" is its position */
- }
- tstadr -> lnk_chpri = ch_ind;
- tstadr -> lnk_host = strdup (hostr);
- tstadr -> lnk_mbox = strdup (mbox);
-
- return (lnk_insrt (tstadr));
- }
- /**/
-
- LOCFUN
- lnk_insrt (newadr) /* insert addr into list, sorted */
- register struct lnk_struct *newadr;
- {
- register struct lnk_struct *curadr,
- *lastptr;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "lnk_insrt ()");
- #endif
- for (curadr = lnk_strt.lnk_nxt, lastptr = &lnk_strt;
- curadr != 0; lastptr = curadr, curadr = curadr -> lnk_nxt)
- { /* skip until new entry is "smaller" */
- switch (lnk_cmpr (newadr, curadr))
- {
- case 1: /* newadr > curadr */
- continue;
-
- case 0: /* duplicate entries are ignored */
- return (OK); /* noop */
- }
- break; /* returned -1 => curadr > newadr */
- } /* otherwise tack on end of list */
- lnk_nentries++; /* any kind of entry */
- if (newadr -> lnk_ch != (Chan *) 0)
- lnk_nadrs++; /* actual addresses */
- lastptr -> lnk_nxt = newadr; /* insert after last one smaller */
- newadr -> lnk_nxt = curadr; /* than new one */
- return (DONE); /* really did something */
- }
-
- /*
- * In order to avoid O(n*2) sorting behavior, this comparison
- * routine will cause the addresses to be sorted in reverse
- * alphabetical order. The address list is reversed before
- * being written out.
- */
- LOCFUN
- lnk_cmpr (adr1, adr2) /* determine sort relationship */
- register struct lnk_struct *adr1,
- *adr2;
- { /* sort on chan, host, then mailbox */
- register short adr_rel; /* relationship between addresses */
-
- adr_rel = adr2 -> lnk_chpri - adr1 -> lnk_chpri;
- /* compare "priorities" of channels */
- if (adr_rel < 0)
- return (-1); /* chan2 > chan1 */
-
- if (adr_rel > 0)
- return (1); /* chan1 > chan2 */
-
- if ((adr_rel = lexrel (adr2 -> lnk_host, adr1 -> lnk_host)) != 0)
- return (adr_rel); /* host spec was different */
-
- return (lexrel (adr2 -> lnk_mbox, adr1 -> lnk_mbox));
- /* well, maybe different mailboxes */
- }
- /**/
-
- LOCFUN struct lnk_struct *
- lnk_1free (adr)
- /* free storage for an entry */
- register struct lnk_struct *adr;
- {
- register struct lnk_struct *nxtadr;
-
- if (adr == 0)
- return (0); /* ain't nothin' here */
- free (adr -> lnk_mbox);
- free (adr -> lnk_host);
- nxtadr = adr -> lnk_nxt;
- free ((char *) adr);
- return (nxtadr);
- }
-
- lnk_freeall () /* step through list and free storage */
- {
- register struct lnk_struct *curadr;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "lnk_freeall()");
- #endif
- for (curadr = lnk_strt.lnk_nxt; curadr != 0; curadr = lnk_1free (curadr));
- lnk_strt.lnk_nxt = 0; /* indicate end-of-list at base */
- lnk_nadrs = 0;
- }
-
- lnk_filall (flags) /* copy the list out to the file */
- {
- register struct lnk_struct *prev;
- register struct lnk_struct *cur;
- register struct lnk_struct *next;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "lnk_filall: %d addrs...", lnk_nadrs);
- #endif
-
- if (lnk_nadrs <= 0 || lnk_strt.lnk_nxt == 0)
- err_msg (RP_NDEL, "no addressees!");
-
- if (lnk_nadrs > lnk_listsize) /* long lists => less verbosity */
- mq_adinit (NO, flags | ADR_CITE, mgt_return);
- else /* initialize address list queue */
- mq_adinit (YES, flags, mgt_return); /* permit delay warning message */
-
- /* Invert the list to get it back in alphabetical order */
- prev = lnk_strt.lnk_nxt;
- cur = prev->lnk_nxt;
- prev->lnk_nxt = 0;
- while (cur != 0) {
- next = cur->lnk_nxt;
- cur->lnk_nxt = prev;
- prev = cur;
- cur = next;
- }
- lnk_strt.lnk_nxt = prev;
-
- /* step through list & store entries */
- for (cur = lnk_strt.lnk_nxt; cur != 0; cur = cur -> lnk_nxt)
- if (cur -> lnk_ch != (Chan *) 0)
- mq_adwrite (cur -> lnk_ch, cur -> lnk_host, cur -> lnk_mbox);
- }
-