+
+/*
+ * Routines/code to support the duplicate address suppression code, adapted
+ * from replsbr.c
+ */
+
+static char *buf; /* our current working buffer */
+static char *bufend; /* end of working buffer */
+static char *last_dst; /* buf ptr at end of last call */
+static unsigned int bufsiz=0; /* current size of buf */
+
+#define BUFINCR 512 /* how much to expand buf when if fills */
+
+#define CPY(s) { cp = (s); while ((*dst++ = *cp++)) ; --dst; }
+
+/*
+ * check if there's enough room in buf for str.
+ * add more mem if needed
+ */
+#define CHECKMEM(str) \
+ if ((len = strlen (str)) >= bufend - dst) {\
+ int i = dst - buf;\
+ int n = last_dst - buf;\
+ bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
+ buf = mh_xrealloc (buf, bufsiz);\
+ dst = buf + i;\
+ last_dst = buf + n;\
+ bufend = buf + bufsiz;\
+ }
+
+
+/*
+ * These are versions of similar routines from replsbr.c; the purpose is
+ * to suppress duplicate addresses from being added to a list when building
+ * up addresses for the %(formataddr) format function. This is used by
+ * repl to prevent duplicate addresses from being added to the "to" line.
+ * See replsbr.c for more information.
+ *
+ * We can't use the functions in replsbr.c directly because they are slightly
+ * different and depend on the rest of replsbr.c
+ */
+static char *
+test_formataddr (char *orig, char *str)
+{
+ register int len;
+ char error[BUFSIZ];
+ register int isgroup;
+ register char *dst;
+ register char *cp;
+ register char *sp;
+ register struct mailname *mp = NULL;
+
+ /* if we don't have a buffer yet, get one */
+ if (bufsiz == 0) {
+ buf = mh_xmalloc (BUFINCR);
+ last_dst = buf; /* XXX */
+ bufsiz = BUFINCR - 6; /* leave some slop */
+ bufend = buf + bufsiz;
+ }
+ /*
+ * If "orig" points to our buffer we can just pick up where we
+ * left off. Otherwise we have to copy orig into our buffer.
+ */
+ if (orig == buf)
+ dst = last_dst;
+ else if (!orig || !*orig) {
+ dst = buf;
+ *dst = '\0';
+ } else {
+ dst = last_dst; /* XXX */
+ CHECKMEM (orig);
+ CPY (orig);
+ }
+
+ /* concatenate all the new addresses onto 'buf' */
+ for (isgroup = 0; (cp = getname (str)); ) {
+ if ((mp = getm (cp, NULL, 0, error, sizeof(error))) == NULL) {
+ fprintf(stderr, "bad address \"%s\" -- %s\n", cp, error);
+ continue;
+ }
+ if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
+ *dst++ = ';';
+ isgroup = 0;
+ }
+ if (insert (mp)) {
+ /* if we get here we're going to add an address */
+ if (dst != buf) {
+ *dst++ = ',';
+ *dst++ = ' ';
+ }
+ if (mp->m_gname) {
+ CHECKMEM (mp->m_gname);
+ CPY (mp->m_gname);
+ isgroup++;
+ }
+ sp = adrformat (mp);
+ CHECKMEM (sp);
+ CPY (sp);
+ }
+ }
+
+ if (isgroup)
+ *dst++ = ';';
+
+ *dst = '\0';
+ last_dst = dst;
+ return (buf);
+}
+
+
+/*
+ * The companion to test_formataddr(); it behaves the same way, except doesn't
+ * do duplicate address detection.
+ */
+static char *
+test_concataddr(char *orig, char *str)
+{
+ char *cp;
+
+ nodupcheck = 1;
+ cp = test_formataddr(orig, str);
+ nodupcheck = 0;
+ return cp;
+}
+
+static int
+insert (struct mailname *np)
+{
+ struct mailname *mp;
+
+ if (nodupcheck)
+ return 1;
+
+ if (np->m_mbox == NULL)
+ return 0;
+
+ for (mp = &mq; mp->m_next; mp = mp->m_next) {
+ if (!strcasecmp (np->m_host ? np->m_host : "",
+ mp->m_next->m_host ? mp->m_next->m_host : "") &&
+ !strcasecmp (np->m_mbox ? np->m_mbox : "",
+ mp->m_next->m_mbox ? mp->m_next->m_mbox : ""))
+ return 0;
+ }
+ if (!ccme && ismymbox (np))
+ return 0;
+
+ mp->m_next = np;
+
+ return 1;
+}
+
+/*
+ * Reset our duplicate address list
+ */
+
+void
+mlistfree(void)
+{
+ struct mailname *mp, *mp2;
+
+ for (mp = mq.m_next; mp; mp = mp2) {
+ mp2 = mp->m_next;
+ mnfree(mp);
+ }
+}