1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
/*
* fmt_addr.c -- format an address field (from fmt_scan)
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
*/
#include <h/mh.h>
#include <h/addrsbr.h>
#include <h/fmt_scan.h>
#include <h/utils.h>
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; /* 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;\
}
/* fmt_scan will call this routine if the user includes the function
* "(formataddr {component})" in a format string. "orig" is the
* original contents of the string register. "str" is the address
* string to be formatted and concatenated onto orig. This routine
* returns a pointer to the concatenated address string.
*
* We try to not do a lot of malloc/copy/free's (which is why we
* don't call "getcpy") but still place no upper limit on the
* length of the result string.
*
* This routine is placed in a separate library so it can be
* overridden by particular programs (e.g., "replsbr").
*/
char *
formataddr (char *orig, char *str)
{
register int len;
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, NULL, 0)) == NULL)
continue;
if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
*dst++ = ';';
isgroup = 0;
}
/* 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);
mnfree (mp);
}
if (isgroup)
*dst++ = ';';
*dst = '\0';
last_dst = dst;
return (buf);
}
char *concataddr (char *orig, char *str)
{
return formataddr(orig, str);
}
|