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