|
|
@ -128,107 +128,166 @@ fail:
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
|
|
|
skip_comment(char *s)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (*s != '(')
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long d = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
else if (*s == '(')
|
|
|
|
|
|
|
|
d++;
|
|
|
|
|
|
|
|
else if (*s == ')')
|
|
|
|
|
|
|
|
d--;
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
} while (d > 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// always 0 terminates
|
|
|
|
|
|
|
|
// never writes more than dstmax to dst
|
|
|
|
|
|
|
|
// returns how many bytes were appended
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
|
|
|
|
safe_append(char *dst, size_t dstmax, char *strbeg, char *strend)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t dstlen = strlen(dst);
|
|
|
|
|
|
|
|
if (dstmax - dstlen - 1 < strend - strbeg)
|
|
|
|
|
|
|
|
strend = strbeg + (dstmax - dstlen - 1);
|
|
|
|
|
|
|
|
memcpy(dst + dstlen, strbeg, strend - strbeg);
|
|
|
|
|
|
|
|
dst[dstlen + (strend - strbeg) + 1] = 0;
|
|
|
|
|
|
|
|
return strend - strbeg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
|
|
|
|
safe_append_space(char *dst, size_t dstmax)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char sp[] = " ";
|
|
|
|
|
|
|
|
char *se = sp + 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return safe_append(dst, dstmax, sp, se);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
char *
|
|
|
|
blaze822_addr(char *s, char **dispo, char **addro)
|
|
|
|
blaze822_addr(char *s, char **dispo, char **addro)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
static char disp[1024];
|
|
|
|
static char disp[1024];
|
|
|
|
static char addr[1024];
|
|
|
|
static char addr[1024];
|
|
|
|
char *c, *e;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (iswsp(*s))
|
|
|
|
memset(addr, 0, sizeof addr);
|
|
|
|
s++;
|
|
|
|
memset(disp, 0, sizeof disp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char ttok[1024] = { 0 };
|
|
|
|
|
|
|
|
char *tc = ttok;
|
|
|
|
|
|
|
|
char *te = ttok + sizeof ttok;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int not_addr = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
|
|
|
if (!*s || iswsp(*s) || *s == ',' || *s == ';') {
|
|
|
|
|
|
|
|
if (tc != ttok) {
|
|
|
|
|
|
|
|
if (!*addr && !not_addr && memchr(ttok, '@', tc - ttok)) {
|
|
|
|
|
|
|
|
safe_append(addr, sizeof addr, ttok, tc);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (*disp)
|
|
|
|
|
|
|
|
safe_append_space(disp, sizeof disp);
|
|
|
|
|
|
|
|
safe_append(disp, sizeof disp,
|
|
|
|
|
|
|
|
ttok, tc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
tc = ttok;
|
|
|
|
|
|
|
|
not_addr = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (!*s) {
|
|
|
|
if (!*s) {
|
|
|
|
|
|
|
|
if (!*addr && !*disp) {
|
|
|
|
if (dispo) *dispo = 0;
|
|
|
|
if (dispo) *dispo = 0;
|
|
|
|
if (addro) *addro = 0;
|
|
|
|
if (addro) *addro = 0;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
c = disp;
|
|
|
|
}
|
|
|
|
e = disp + sizeof disp - 1;
|
|
|
|
if (*s == ',' || *s == ';') {
|
|
|
|
|
|
|
|
s++;
|
|
|
|
*disp = 0;
|
|
|
|
if (*addr || *disp)
|
|
|
|
*addr = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
while (*s && c < e) {
|
|
|
|
s++;
|
|
|
|
startover:
|
|
|
|
} else if (*s == '<') {
|
|
|
|
if (*s == '<') {
|
|
|
|
char tok[1024] = { 0 };
|
|
|
|
char *c = addr;
|
|
|
|
char *c = tok;
|
|
|
|
char *e = addr + sizeof addr;
|
|
|
|
char *e = tok + sizeof tok;
|
|
|
|
|
|
|
|
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
while (*s && c < e && *s != '>') {
|
|
|
|
while (*s && c < e && *s != '>') {
|
|
|
|
if (*s == '<') {
|
|
|
|
s = skip_comment(s);
|
|
|
|
goto startover;
|
|
|
|
if (*s == '"') {
|
|
|
|
} else if (*s == '"') {
|
|
|
|
|
|
|
|
// local part may be quoted, allow all
|
|
|
|
// local part may be quoted, allow all
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
while (*s && c < e && *s != '"')
|
|
|
|
while (*s && c < e && *s != '"') {
|
|
|
|
|
|
|
|
if (*s == '\\')
|
|
|
|
|
|
|
|
s++;
|
|
|
|
*c++ = *s++;
|
|
|
|
*c++ = *s++;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (*s == '"')
|
|
|
|
if (*s == '"')
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (iswsp(*s))
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
else
|
|
|
|
*c++ = *s++;
|
|
|
|
*c++ = *s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*s == '>')
|
|
|
|
if (*s == '>')
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
while (iswsp(*s))
|
|
|
|
safe_append(addr, sizeof addr, tok, c);
|
|
|
|
s++;
|
|
|
|
|
|
|
|
*c = 0;
|
|
|
|
|
|
|
|
} else if (*s == '"') {
|
|
|
|
} else if (*s == '"') {
|
|
|
|
|
|
|
|
char tok[1024] = { 0 };
|
|
|
|
|
|
|
|
char *c = tok;
|
|
|
|
|
|
|
|
char *e = tok + sizeof tok;
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
while (*s && c < e && *s != '"') {
|
|
|
|
while (*s && c < e && *s != '"') {
|
|
|
|
if (*s == '\\' && *(s+1))
|
|
|
|
if (*s == '\\')
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
*c++ = *s++;
|
|
|
|
*c++ = *s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*s == '"')
|
|
|
|
if (*s == '"')
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
} else if (*s == '(') { // XXX recurse to conform?
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!*addr) { // assume: user@host (name)
|
|
|
|
|
|
|
|
*c-- = 0;
|
|
|
|
|
|
|
|
while (c > disp && iswsp(*c))
|
|
|
|
|
|
|
|
*c-- = 0;
|
|
|
|
|
|
|
|
c++;
|
|
|
|
|
|
|
|
memcpy(addr, disp, (c - disp) + 1);
|
|
|
|
|
|
|
|
c = disp;
|
|
|
|
|
|
|
|
*c = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (*s && c < e && *s != ')')
|
|
|
|
if (memchr(tok, '@', c - tok))
|
|
|
|
*c++ = *s++;
|
|
|
|
not_addr = 1; // @ inside "" is never an addr
|
|
|
|
if (*s == ')')
|
|
|
|
|
|
|
|
s++;
|
|
|
|
if (tc != ttok)
|
|
|
|
} else if (*s == '\\') {
|
|
|
|
tc += safe_append_space(ttok, sizeof ttok);
|
|
|
|
s++;
|
|
|
|
tc += safe_append(ttok, sizeof ttok, tok, c);
|
|
|
|
if (*s)
|
|
|
|
} else if (*s == '(') {
|
|
|
|
*c++ = *s++;
|
|
|
|
char *z = skip_comment(s);
|
|
|
|
|
|
|
|
if (!*disp && *addr) // user@host (name)
|
|
|
|
|
|
|
|
safe_append(disp, sizeof disp, s + 1, z - 1);
|
|
|
|
|
|
|
|
else if (*disp) { // copy comment
|
|
|
|
|
|
|
|
safe_append_space(disp, sizeof disp);
|
|
|
|
|
|
|
|
safe_append(disp, sizeof disp, s, z);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
s = z;
|
|
|
|
} else if (*s == ':') {
|
|
|
|
} else if (*s == ':') {
|
|
|
|
|
|
|
|
if (memchr(ttok, '[', tc - ttok)) {
|
|
|
|
|
|
|
|
// in ipv6 address
|
|
|
|
|
|
|
|
if (tc < te)
|
|
|
|
|
|
|
|
*tc++ = *s++;
|
|
|
|
|
|
|
|
} else { // ignore group name and start over
|
|
|
|
s++;
|
|
|
|
s++;
|
|
|
|
while (iswsp(*s))
|
|
|
|
tc = ttok;
|
|
|
|
s++;
|
|
|
|
memset(addr, 0, sizeof addr);
|
|
|
|
c = disp; // forget already read group name
|
|
|
|
memset(disp, 0, sizeof disp);
|
|
|
|
} else if (*s == ',' || *s == ';') {
|
|
|
|
*ttok = 0;
|
|
|
|
s++;
|
|
|
|
not_addr = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
*c++ = *s++;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (*s == '\\' && *(s+1))
|
|
|
|
|
|
|
|
s++;
|
|
|
|
|
|
|
|
if (tc < te)
|
|
|
|
|
|
|
|
*tc++ = *s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*c-- = 0;
|
|
|
|
|
|
|
|
// strip trailing ws
|
|
|
|
|
|
|
|
while (c > disp && iswsp(*c))
|
|
|
|
|
|
|
|
*c-- = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (*disp && !*addr && strchr(disp, '@')) {
|
|
|
|
|
|
|
|
// just mail address was given
|
|
|
|
|
|
|
|
c++;
|
|
|
|
|
|
|
|
memcpy(addr, disp, (c - disp) + 1);
|
|
|
|
|
|
|
|
*disp = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *host = strrchr(addr, '@');
|
|
|
|
char *host = strrchr(addr, '@');
|
|
|
|