#include <sys_defs.h>
#include <string.h>
#include <ctype.h>
#include <vstring.h>
#include "quote_822_local.h"
#define YES 1
#define NO 0
static int is_822_dot_string(const char *local_part, const char *end, int flags)
{
const char *cp;
int ch;
if (local_part == end || local_part[0] == 0 || local_part[0] == '.')
return (NO);
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if (ch == '.' && (cp + 1) < end && cp[1] == '.')
return (NO);
if (ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
return (NO);
if (ch == ' ')
return (NO);
if (ISCNTRL(ch))
return (NO);
if (ch == '(' || ch == ')'
|| ch == '<' || ch == '>'
|| (ch == '@' && !(flags & QUOTE_FLAG_EXPOSE_AT)) || ch == ','
|| ch == ';' || ch == ':'
|| ch == '\\' || ch == '"'
|| ch == '[' || ch == ']')
return (NO);
}
if (cp[-1] == '.')
return (NO);
return (YES);
}
static VSTRING *make_822_quoted_string(VSTRING *dst, const char *local_part,
const char *end, int flags)
{
const char *cp;
int ch;
VSTRING_ADDCH(dst, '"');
for (cp = local_part; cp < end && (ch = *(unsigned char *) cp) != 0; cp++) {
if ((ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
|| ch == '"' || ch == '\\' || ch == '\r')
VSTRING_ADDCH(dst, '\\');
VSTRING_ADDCH(dst, ch);
}
VSTRING_ADDCH(dst, '"');
return (dst);
}
VSTRING *quote_822_local_flags(VSTRING *dst, const char *mbox, int flags)
{
const char *start;
const char *end;
const char *colon;
if (mbox[0] == '@' && (colon = strchr(mbox, ':')) != 0)
start = colon + 1;
else
start = mbox;
if ((end = strrchr(start, '@')) == 0)
end = start + strlen(start);
if ((flags & QUOTE_FLAG_APPEND) == 0)
VSTRING_RESET(dst);
if (is_822_dot_string(start, end, flags)) {
return (vstring_strcat(dst, mbox));
} else {
vstring_strncat(dst, mbox, start - mbox);
make_822_quoted_string(dst, start, end, flags & QUOTE_FLAG_8BITCLEAN);
return (vstring_strcat(dst, end));
}
}
VSTRING *unquote_822_local(VSTRING *dst, const char *mbox)
{
const char *start;
const char *end;
const char *colon;
const char *cp;
if (mbox[0] == '@' && (colon = strchr(mbox, ':')) != 0) {
start = colon + 1;
vstring_strncpy(dst, mbox, start - mbox);
} else {
start = mbox;
VSTRING_RESET(dst);
}
if ((end = strrchr(start, '@')) == 0)
end = start + strlen(start);
for (cp = start; cp < end; cp++) {
if (*cp == '"')
continue;
if (*cp == '\\') {
if (cp[1] == 0)
continue;
cp++;
}
VSTRING_ADDCH(dst, *cp);
}
if (*end)
vstring_strcat(dst, end);
else
VSTRING_TERMINATE(dst);
return (dst);
}
#ifdef TEST
#include <vstream.h>
#include <vstring_vstream.h>
#define STR vstring_str
int main(int unused_argc, char **unused_argv)
{
VSTRING *raw = vstring_alloc(100);
VSTRING *quoted = vstring_alloc(100);
VSTRING *unquoted = vstring_alloc(100);
while (vstring_fgets_nonl(raw, VSTREAM_IN)) {
quote_822_local(quoted, STR(raw));
vstream_printf("quoted: %s\n", STR(quoted));
unquote_822_local(unquoted, STR(quoted));
vstream_printf("unquoted: %s\n", STR(unquoted));
vstream_fflush(VSTREAM_OUT);
}
vstring_free(unquoted);
vstring_free(quoted);
vstring_free(raw);
return (0);
}
#endif