mail_addr_crunch.c [plain text]
#include <sys_defs.h>
#include <string.h>
#include <mymalloc.h>
#include <argv.h>
#include <vstring.h>
#include <tok822.h>
#include <canon_addr.h>
#include <quote_822_local.h>
#include <mail_addr_crunch.h>
ARGV *mail_addr_crunch_opt(const char *string, const char *extension,
int in_form, int out_form)
{
VSTRING *intern_addr = vstring_alloc(100);
VSTRING *extern_addr = vstring_alloc(100);
VSTRING *canon_addr = vstring_alloc(100);
ARGV *argv = argv_alloc(1);
TOK822 *tree;
TOK822 **addr_list;
TOK822 **tpp;
char *ratsign;
ssize_t extlen;
if (extension)
extlen = strlen(extension);
#define STR(x) vstring_str(x)
if (in_form == MA_FORM_INTERNAL) {
quote_822_local(extern_addr, string);
string = STR(extern_addr);
}
if (*string == 0 || strcmp(string, "<>") == 0)
string = "\"\"";
tree = tok822_parse(string);
string = 0;
addr_list = tok822_grep(tree, TOK822_ADDR);
for (tpp = addr_list; *tpp; tpp++) {
tok822_externalize(extern_addr, tpp[0]->head, TOK822_STR_DEFL);
canon_addr_external(canon_addr, STR(extern_addr));
unquote_822_local(intern_addr, STR(canon_addr));
if (extension && strchr(STR(intern_addr), *extension) == 0) {
VSTRING_SPACE(intern_addr, extlen + 1);
if ((ratsign = strrchr(STR(intern_addr), '@')) == 0) {
vstring_strcat(intern_addr, extension);
} else {
memmove(ratsign + extlen, ratsign, strlen(ratsign) + 1);
memcpy(ratsign, extension, extlen);
VSTRING_SKIP(intern_addr);
}
}
if (out_form == MA_FORM_EXTERNAL) {
quote_822_local(extern_addr, STR(intern_addr));
argv_add(argv, STR(extern_addr), ARGV_END);
} else {
argv_add(argv, STR(intern_addr), ARGV_END);
}
}
argv_terminate(argv);
myfree((void *) addr_list);
tok822_free_tree(tree);
vstring_free(canon_addr);
vstring_free(extern_addr);
vstring_free(intern_addr);
return (argv);
}
#ifdef TEST
#include <stdlib.h>
#include <unistd.h>
#include <msg.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <mail_conf.h>
#include <mail_params.h>
VSTRING *canon_addr_external(VSTRING *result, const char *addr)
{
return (vstring_strcpy(result, addr));
}
static int get_addr_form(const char *prompt, VSTRING *buf)
{
int addr_form;
if (prompt) {
vstream_printf("%s: ", prompt);
vstream_fflush(VSTREAM_OUT);
}
if (vstring_get_nonl(buf, VSTREAM_IN) == VSTREAM_EOF)
exit(0);
if ((addr_form = mail_addr_form_from_string(STR(buf))) < 0)
msg_fatal("bad address form: %s", STR(buf));
return (addr_form);
}
int main(int unused_argc, char **unused_argv)
{
VSTRING *extension = vstring_alloc(1);
VSTRING *buf = vstring_alloc(1);
ARGV *argv;
char **cpp;
int do_prompt = isatty(0);
int in_form;
int out_form;
mail_conf_read();
if (chdir(var_queue_dir) < 0)
msg_fatal("chdir %s: %m", var_queue_dir);
in_form = get_addr_form(do_prompt ? "input form" : 0, buf);
out_form = get_addr_form(do_prompt ? "output form" : 0, buf);
if (do_prompt) {
vstream_printf("extension: (CR for none): ");
vstream_fflush(VSTREAM_OUT);
}
if (vstring_get_nonl(extension, VSTREAM_IN) == VSTREAM_EOF)
exit(0);
if (do_prompt) {
vstream_printf("print strings to be translated, one per line\n");
vstream_fflush(VSTREAM_OUT);
}
while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
argv = mail_addr_crunch_opt(STR(buf), (VSTRING_LEN(extension) ?
STR(extension) : 0),
in_form, out_form);
for (cpp = argv->argv; *cpp; cpp++)
vstream_printf("|%s|\n", *cpp);
vstream_fflush(VSTREAM_OUT);
argv_free(argv);
}
vstring_free(extension);
vstring_free(buf);
return (0);
}
#endif