]> diplodocus.org Git - nmh/blob - sbr/fmt_addr.c
Fix invalid pointer arithmetic.
[nmh] / sbr / fmt_addr.c
1 /* fmt_addr.c -- format an address field (from fmt_scan)
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/addrsbr.h>
10 #include <h/fmt_scan.h>
11 #include <h/utils.h>
12
13 static char *buf; /* our current working buffer */
14 static char *bufend; /* end of working buffer */
15 static char *last_dst; /* buf ptr at end of last call */
16 static unsigned int bufsiz; /* current size of buf */
17
18 #define BUFINCR 512 /* how much to expand buf when if fills */
19
20 #define CPY(s) { cp = (s); while ((*dst++ = *cp++)) ; --dst; }
21
22 /* check if there's enough room in buf for str. add more mem if needed */
23 #define CHECKMEM(str) \
24 if ((len = strlen (str)) >= bufend - dst) {\
25 int i = dst - buf;\
26 int n = last_dst - buf;\
27 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
28 buf = mh_xrealloc (buf, bufsiz);\
29 dst = buf + i;\
30 last_dst = buf + n;\
31 bufend = buf + bufsiz;\
32 }
33
34
35 /* fmt_scan will call this routine if the user includes the function
36 * "(formataddr {component})" in a format string. "orig" is the
37 * original contents of the string register. "str" is the address
38 * string to be formatted and concatenated onto orig. This routine
39 * returns a pointer to the concatenated address string.
40 *
41 * We try to not do a lot of malloc/copy/free's (which is why we
42 * don't call "getcpy") but still place no upper limit on the
43 * length of the result string.
44 *
45 * This routine is placed in a separate library so it can be
46 * overridden by particular programs (e.g., "replsbr").
47 */
48
49 char *
50 formataddr (char *orig, char *str)
51 {
52 int len;
53 int isgroup;
54 char *dst;
55 char *cp;
56 char *sp;
57 struct mailname *mp = NULL;
58
59 /* if we don't have a buffer yet, get one */
60 if (bufsiz == 0) {
61 buf = mh_xmalloc (BUFINCR);
62 last_dst = buf; /* XXX */
63 bufsiz = BUFINCR - 6; /* leave some slop */
64 bufend = buf + bufsiz;
65 }
66 /*
67 * If "orig" points to our buffer we can just pick up where we
68 * left off. Otherwise we have to copy orig into our buffer.
69 */
70 if (orig == buf)
71 dst = last_dst;
72 else if (!orig || !*orig) {
73 dst = buf;
74 *dst = '\0';
75 } else {
76 dst = last_dst; /* XXX */
77 CHECKMEM (orig);
78 CPY (orig);
79 }
80
81 /* concatenate all the new addresses onto 'buf' */
82 for (isgroup = 0; (cp = getname (str)); ) {
83 if ((mp = getm (cp, NULL, 0, NULL, 0)) == NULL)
84 continue;
85
86 if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
87 *dst++ = ';';
88 isgroup = 0;
89 }
90 /* if we get here we're going to add an address */
91 if (dst != buf) {
92 *dst++ = ',';
93 *dst++ = ' ';
94 }
95 if (mp->m_gname) {
96 CHECKMEM (mp->m_gname);
97 CPY (mp->m_gname);
98 isgroup++;
99 }
100 sp = adrformat (mp);
101 CHECKMEM (sp);
102 CPY (sp);
103 mnfree (mp);
104 }
105
106 if (isgroup)
107 *dst++ = ';';
108
109 *dst = '\0';
110 last_dst = dst;
111 return buf;
112 }
113
114 char *concataddr (char *orig, char *str)
115 {
116 return formataddr(orig, str);
117 }