#include #include #include #include "eps.h" static void address_fixup(address_t *); group_t *address_evaluate(const char *data) { group_t *g = NULL; char *d = NULL, *h = NULL, *t = NULL; address_t *alist = NULL, *a = NULL, *a_tail = NULL; g = (group_t *)malloc(sizeof(group_t)); if (g == NULL) return NULL; alist = (address_t *)malloc(sizeof(address_t)); if (alist == NULL) { free(g); return NULL; } a_tail = alist; alist->next = NULL; g->group = NULL; g->members = a_tail; g->nmembers = 0; /* address_evaluate_one mangles data */ d = mstrdup((char *)data); if (d == NULL) { free(g); free(alist); return NULL; } t = d; h = rfc2822_next_token(d, ':', "<>;"); if (*h == ':') { *h++ = '\0'; g->group = mstrdup(t); while((*h == ' ') || (*h == '\t')) h++; t = h; } else h = t = d; while(1) { h = rfc2822_next_token(t, ',', NULL); if (!(*h)) break; *h = '\0'; a = address_evaluate_one(t); if (!a) break; a_tail->next = a; a->next = NULL; a_tail = a; g->nmembers++; t = (h + 1); } if (*t) { a = address_evaluate_one(t); if (a) { a_tail->next = a; a->next = NULL; a_tail = a; g->nmembers++; } } if (g->group) { h = rfc2822_convert_literals(g->group); free(g->group); g->group = h; } free(d); return g; } address_t *address_evaluate_one(char *data) { address_t *a = NULL; char *p = NULL, *n = NULL, *u = NULL, *h = NULL, *d = NULL; n = u = d = NULL; a = (address_t *)malloc(sizeof(address_t)); if (a == NULL) return NULL; memset((address_t *)a, 0, sizeof(address_t)); p = data; /* Name/User */ h = rfc2822_next_token(data, '<', NULL); if (*h == '<') { *h++ = '\0'; if (*p) n = data; if (*h) u = h; else return a; for (p = (h - 2); ((p > data) && ((*p == ' ') || (*p == '\t'))); p--); *(++p) = '\0'; p = h; if ((n) && (*n)) a->name = mstrdup(n); } /* User/Domain */ h = rfc2822_next_token(p, '@', ">"); if (*h == '@') { *h++ = '\0'; if (!(*h)) return a; if (!u) { while((*p == ' ') || (*p == '\t')) p++; u = p; } d = p = h; } else return a; a->user = mstrdup(u); /* End */ h = rfc2822_next_token(p, '>', " "); if (*h == '>') *h = '\0'; a->domain = mstrdup(d); address_fixup(a); return a; } void address_kill(group_t *g) { address_t *a = NULL, *ao = NULL; if (g->members) { a = g->members; while(a->next) { ao = a->next; a->next = a->next->next; address_kill_one(ao); } free(g->members); } free(g); } void address_kill_one(address_t *a) { if (!a) return; if (a->name) free(a->name); if (a->user) free(a->user); if (a->domain) free(a->domain); free(a); } void address_fixup(address_t *a) { char *p = NULL; if (!a) return; if (a->name) { p = rfc2822_convert_literals(a->name); free(a->name); a->name = p; } }