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 | |
---|
12 | static char *buf; /* our current working buffer */ |
---|
13 | static char *bufend; /* end of working buffer */ |
---|
14 | static char *last_dst; /* buf ptr at end of last call */ |
---|
15 | static 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 | |
---|
50 | char * |
---|
51 | formataddr (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 | } |
---|