source: trunk/third/nmh/sbr/fmt_addr.c @ 12455

Revision 12455, 3.0 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * fmt_addr.c -- format an address field (from fmt_scan)
4 *
5 * $Id: fmt_addr.c,v 1.1.1.1 1999-02-07 18:14:08 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <h/addrsbr.h>
10#include <h/fmt_scan.h>
11
12static char *buf;               /* our current working buffer  */
13static char *bufend;            /* end of working buffer       */
14static char *last_dst;          /* buf ptr at end of last call */
15static unsigned int bufsiz;     /* current size of buf         */
16
17#define BUFINCR 512             /* how much to expand buf when if fills */
18
19#define CPY(s) { cp = (s); while ((*dst++ = *cp++)) ; --dst; }
20
21/* check if there's enough room in buf for str.  add more mem if needed */
22#define CHECKMEM(str) \
23            if ((len = strlen (str)) >= bufend - dst) {\
24                int i = dst - buf;\
25                int n = last_dst - buf;\
26                bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
27                buf = realloc (buf, bufsiz);\
28                dst = buf + i;\
29                last_dst = buf + n;\
30                if (! buf)\
31                    adios (NULL, "formataddr: couldn't get buffer space");\
32                bufend = buf + bufsiz;\
33            }
34
35
36/* fmt_scan will call this routine if the user includes the function
37 * "(formataddr {component})" in a format string.  "orig" is the
38 * original contents of the string register.  "str" is the address
39 * string to be formatted and concatenated onto orig.  This routine
40 * returns a pointer to the concatenated address string.
41 *
42 * We try to not do a lot of malloc/copy/free's (which is why we
43 * don't call "getcpy") but still place no upper limit on the
44 * length of the result string.
45 *
46 * This routine is placed in a separate library so it can be
47 * overridden by particular programs (e.g., "replsbr").
48 */
49
50char *
51formataddr (char *orig, char *str)
52{
53    register int len;
54    register int isgroup;
55    register char *dst;
56    register char *cp;
57    register char *sp;
58    register struct mailname *mp = NULL;
59
60    /* if we don't have a buffer yet, get one */
61    if (bufsiz == 0) {
62        buf = malloc (BUFINCR);
63        if (! buf)
64            adios (NULL, "formataddr: couldn't allocate buffer space");
65        last_dst = buf;         /* XXX */
66        bufsiz = BUFINCR - 6;  /* leave some slop */
67        bufend = buf + bufsiz;
68    }
69    /*
70     * If "orig" points to our buffer we can just pick up where we
71     * left off.  Otherwise we have to copy orig into our buffer.
72     */
73    if (orig == buf)
74        dst = last_dst;
75    else if (!orig || !*orig) {
76        dst = buf;
77        *dst = '\0';
78    } else {
79        dst = last_dst;         /* XXX */
80        CHECKMEM (orig);
81        CPY (orig);
82    }
83
84    /* concatenate all the new addresses onto 'buf' */
85    for (isgroup = 0; cp = getname (str); ) {
86        if ((mp = getm (cp, NULL, 0, fmt_norm, NULL)) == NULL)
87            continue;
88
89        if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
90            *dst++ = ';';
91            isgroup = 0;
92        }
93        /* if we get here we're going to add an address */
94        if (dst != buf) {
95            *dst++ = ',';
96            *dst++ = ' ';
97        }
98        if (mp->m_gname) {
99            CHECKMEM (mp->m_gname);
100            CPY (mp->m_gname);
101            isgroup++;
102        }
103        sp = adrformat (mp);
104        CHECKMEM (sp);
105        CPY (sp);
106        mnfree (mp);
107    }
108
109    if (isgroup)
110        *dst++ = ';';
111
112    *dst = '\0';
113    last_dst = dst;
114    return (buf);
115}
Note: See TracBrowser for help on using the repository browser.