home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / submit / lnk_submit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  7.5 KB  |  233 lines

  1. #include "util.h"
  2. #include "mmdf.h"
  3. #include "ch.h"
  4. #include "adr_queue.h"
  5. #include "msg.h"
  6. /*
  7.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  8.  *     
  9.  *
  10.  *     Copyright (C) 1979,1980,1981  University of Delaware
  11.  *     
  12.  *     Department of Electrical Engineering
  13.  *     University of Delaware
  14.  *     Newark, Delaware  19711
  15.  *
  16.  *     Phone:  (302) 738-1163
  17.  *     
  18.  *     
  19.  *     This program module was developed as part of the University
  20.  *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
  21.  *     
  22.  *     Acquisition, use, and distribution of this module and its listings
  23.  *     are subject restricted to the terms of a license agreement.
  24.  *     Documents describing systems using this module must cite its source.
  25.  *
  26.  *     The above statements must be retained with all copies of this
  27.  *     program and may not be removed without the consent of the
  28.  *     University of Delaware.
  29.  *     
  30.  *
  31.  *     version  -1    David H. Crocker    March   1979
  32.  *     version   0    David H. Crocker    April   1980
  33.  *     version  v7    David H. Crocker    May     1981
  34.  *     version   1    David H. Crocker    October 1981
  35.  *
  36.  */
  37.  
  38. /*      Jun 80  D. Crocker      RP_USER -> RP_NDEL on no valid users
  39.  *      Nov 80  D. Crocker      Reduce verbosity if more than 12 addrs.
  40.  *      Jun 82  D. Crocker      null chan -> source spec
  41.  *      Jul 82  D. Crocker      qf_ -> mq_
  42.  */
  43. extern struct ll_struct *logptr;
  44. extern Chan **ch_tbsrch;         /* for sorting addrs by channel       */
  45. extern char *strdup ();
  46. extern char *mgt_return;         /* sender's return address            */
  47. extern short tracing;
  48. extern int  lnk_listsize;
  49.  
  50. LOCFUN lnk_insrt(), lnk_cmpr();
  51.  
  52. struct lnk_struct
  53. {
  54.     struct lnk_struct   *lnk_nxt; /* where the next entry is            */
  55.     struct ch_struct    *lnk_ch;  /* what delivery pgm to run           */
  56.     short     lnk_chpri;            /* "priority" of chan in ch_tbsrch[]  */
  57.     char   *lnk_host;             /* host part of address               */
  58.     char   *lnk_mbox;             /* mailbox part of address            */
  59. };
  60.  
  61. short  lnk_nadrs;            /* current number of addresses        */
  62. short  lnk_nentries;         /* current number of entries in list  */
  63.  
  64. /* ***************  (lnk_)  ADDRESS LINKED-LIST PRIMITIVES  *********** */
  65.  
  66. LOCVAR struct lnk_struct    lnk_strt;
  67.                   /* 1st address in list                */
  68.  
  69. lnk_adinfo (thechan, hostr, mbox) /* given constituents, add to list    */
  70. Chan *thechan;                 /* internal chan name/code            */
  71. char *hostr,                   /* official name of host              */
  72.      *mbox;                    /* name of mailbox                    */
  73. {
  74.     extern char *ut_alloc ();
  75.     register struct lnk_struct *tstadr;
  76.     register short ch_ind;
  77.  
  78. #ifdef DEBUG
  79.     ll_log (logptr, LLOGBTR, "lnk_adinfo ()");
  80. #endif
  81.  
  82.     /*NOSTRICT*/
  83.     tstadr = (struct lnk_struct *) ut_alloc (sizeof (struct lnk_struct));
  84.     if ((tstadr -> lnk_ch = thechan) == (Chan *) 0)
  85.     ch_ind = -1;            /* really a source specification        */
  86.     else
  87.     {
  88. #ifdef DEBUG
  89.     ll_log (logptr, LLOGFTR, "lnk_adinfo (%s(->%s), %s, %s)",
  90.         thechan -> ch_name, thechan -> ch_queue,
  91.         hostr, mbox);
  92. #endif
  93.         if (tracing) {
  94.         printf("queueing for %s: via '%s': '%s'\n",
  95.         thechan -> ch_name, hostr, mbox);
  96.         fflush(stdout);
  97.     }
  98.     for (ch_ind = 0; ch_tbsrch[ch_ind] != 0 &&
  99.         ch_tbsrch[ch_ind] != thechan; ch_ind++);
  100.                   /* chan's "priority" is its position  */
  101.     }
  102.     tstadr -> lnk_chpri = ch_ind;
  103.     tstadr -> lnk_host = strdup (hostr);
  104.     tstadr -> lnk_mbox = strdup (mbox);
  105.  
  106.     return (lnk_insrt (tstadr));
  107. }
  108. /* */
  109.  
  110. LOCFUN
  111.         lnk_insrt (newadr)      /* insert addr into list, sorted      */
  112. register struct lnk_struct *newadr;
  113. {
  114.     register struct lnk_struct *curadr,
  115.                                *lastptr;
  116.  
  117. #ifdef DEBUG
  118.     ll_log (logptr, LLOGFTR, "lnk_insrt ()");
  119. #endif
  120.     for (curadr = lnk_strt.lnk_nxt, lastptr = &lnk_strt;
  121.         curadr != 0; lastptr = curadr, curadr = curadr -> lnk_nxt)
  122.     {                  /* skip until new entry is "smaller"  */
  123.     switch (lnk_cmpr (newadr, curadr))
  124.     {
  125.         case 1:           /* newadr > curadr                    */
  126.         continue;
  127.  
  128.         case 0:           /* duplicate entries are ignored      */
  129.         return (OK);      /* noop                               */
  130.     }
  131.     break;              /* returned -1 => curadr > newadr     */
  132.     }                  /* otherwise tack on end of list      */
  133.     lnk_nentries++;               /* any kind of entry                  */
  134.     if (newadr -> lnk_ch != (Chan *) 0)
  135.     lnk_nadrs++;              /* actual addresses                   */
  136.     lastptr -> lnk_nxt = newadr;  /* insert after last one smaller      */
  137.     newadr -> lnk_nxt = curadr;   /*    than new one                    */
  138.     return (DONE);                /* really did something               */
  139. }
  140.  
  141. /*
  142.  *    In order to avoid O(n*2) sorting behavior, this comparison
  143.  *    routine will cause the addresses to be sorted in reverse
  144.  *    alphabetical order.  The address list is reversed before
  145.  *    being written out.
  146.  */
  147. LOCFUN
  148.         lnk_cmpr (adr1, adr2)     /* determine sort relationship        */
  149. register struct lnk_struct *adr1,
  150.                            *adr2;
  151. {                  /* sort on chan, host, then mailbox   */
  152.     register short    adr_rel;      /* relationship between addresses     */
  153.  
  154.     adr_rel = adr2 -> lnk_chpri - adr1 -> lnk_chpri;
  155.                   /* compare "priorities" of channels   */
  156.     if (adr_rel < 0)
  157.     return (-1);          /* chan2 > chan1                      */
  158.  
  159.     if (adr_rel > 0)
  160.     return (1);          /* chan1 > chan2                      */
  161.  
  162.     if ((adr_rel = lexrel (adr2 -> lnk_host, adr1 -> lnk_host)) != 0)
  163.     return (adr_rel);      /* host spec was different            */
  164.  
  165.     return (lexrel (adr2 -> lnk_mbox, adr1 -> lnk_mbox));
  166.                   /* well, maybe different mailboxes    */
  167. }
  168. /* */
  169.  
  170. LOCFUN struct lnk_struct   *
  171.                             lnk_1free (adr)
  172.                   /* free storage for an entry          */
  173. register struct lnk_struct *adr;
  174. {
  175.     register struct lnk_struct *nxtadr;
  176.  
  177.     if (adr == 0)
  178.     return (0);          /* ain't nothin' here                 */
  179.     free (adr -> lnk_mbox);
  180.     free (adr -> lnk_host);
  181.     nxtadr = adr -> lnk_nxt;
  182.     free ((char *) adr);
  183.     return (nxtadr);
  184. }
  185.  
  186. lnk_freeall ()                    /* step through list and free storage */
  187. {
  188.     register struct lnk_struct *curadr;
  189.  
  190. #ifdef DEBUG
  191.     ll_log (logptr, LLOGBTR, "lnk_freeall()");
  192. #endif
  193.     for (curadr = lnk_strt.lnk_nxt; curadr != 0; curadr = lnk_1free (curadr));
  194.     lnk_strt.lnk_nxt = 0;         /* indicate end-of-list at base       */
  195.     lnk_nadrs = 0;
  196. }
  197.  
  198. lnk_filall (flags)         /* copy the list out to the file      */
  199. {
  200.     register struct lnk_struct *prev;
  201.     register struct lnk_struct *cur;
  202.     register struct lnk_struct *next;
  203.  
  204. #ifdef DEBUG
  205.     ll_log (logptr, LLOGBTR, "lnk_filall:  %d addrs...", lnk_nadrs);
  206. #endif
  207.  
  208.     if (lnk_nadrs <= 0 || lnk_strt.lnk_nxt == 0)
  209.     err_msg (RP_NDEL, "no addressees!");
  210.  
  211.     if (lnk_nadrs > lnk_listsize)      /* long lists => less verbosity     */
  212.     mq_adinit (NO, flags | ADR_CITE, mgt_return);
  213.     else                            /* initialize address list queue    */
  214.     mq_adinit (YES, flags, mgt_return); /* permit delay warning message */
  215.  
  216.     /*  Invert the list to get it back in alphabetical order  */
  217.     prev = lnk_strt.lnk_nxt;
  218.     cur = prev->lnk_nxt;
  219.     prev->lnk_nxt = 0;
  220.     while (cur != 0) {
  221.     next = cur->lnk_nxt;
  222.         cur->lnk_nxt = prev;
  223.         prev = cur;
  224.         cur = next;
  225.     }
  226.     lnk_strt.lnk_nxt = prev;
  227.  
  228.                 /* step through list & store entries  */
  229.     for (cur = lnk_strt.lnk_nxt; cur != 0; cur = cur -> lnk_nxt)
  230.     if (cur -> lnk_ch != (Chan *) 0)
  231.         mq_adwrite (cur -> lnk_ch, cur -> lnk_host, cur -> lnk_mbox);
  232. }
  233.