static void check_sender() { const char *h=hdr("reply-to"); struct rfc822t *t; struct rfc822a *a; if (!h || !*h) h=hdr("from"); if (!h || !*h) exit(0); t=rfc822t_alloc_new(h, NULL, NULL); if (!t || !(a=rfc822a_alloc(t))) { perror("malloc"); exit(EX_TEMPFAIL); } if (a->naddrs <= 0) exit (0); sender=rfc822_getaddr(a, 0); rfc822a_free(a); rfc822t_free(t); if (!sender || !*sender) exit(0); }
static void check_recips() { char *buf; struct rfc822t *t; struct rfc822a *a; struct header *h; if (!recips || !*recips) return; buf=strdup(recips); if (!buf) { perror("strdup"); exit(EX_TEMPFAIL); } for (h=header_list; h; h=h->next) { int i; if (strncasecmp(h->buf, "to:", 3) && strncasecmp(h->buf, "cc:", 3)) continue; t=rfc822t_alloc_new(h->buf+3, NULL, NULL); if (!t || !(a=rfc822a_alloc(t))) { perror("malloc"); exit(EX_TEMPFAIL); } for (i=0; i<a->naddrs; i++) { char *p=rfc822_getaddr(a, i); char *q; strcpy(buf, recips); for (q=buf; (q=strtok(q, ", ")) != 0; q=0) { if (p && strcasecmp(p, q) == 0) { free(p); free(buf); rfc822a_free(a); rfc822t_free(t); return; } } free(p); } rfc822a_free(a); rfc822t_free(t); } free(buf); exit(0); }
struct rfc822t *rw_rewrite_tokenize(const char *address) { struct rfc822t *tokens=rfc822t_alloc_new(address, NULL, NULL); int i; if (!tokens) clog_msg_errno(); for (i=1; i<tokens->ntokens; i++) tokens->tokens[i-1].next=tokens->tokens+i; return (tokens); }
static int knownkey(const char *shortname, const char *known_keys) { struct rfc822t *t=rfc822t_alloc_new(shortname, NULL, NULL); struct rfc822a *a; int i; if (!t) return (0); a=rfc822a_alloc(t); if (!a) { rfc822t_free(t); return (0); } for (i=0; i<a->naddrs; i++) { char *p=rfc822_getaddr(a, i); int plen; const char *q; if (!p) continue; if (!*p) { free(p); continue; } plen=strlen(p); for (q=known_keys; *q; ) { if (strncasecmp(q, p, plen) == 0 && q[plen] == '\n') { free(p); rfc822a_free(a); rfc822t_free(t); return (1); } while (*q) if (*q++ == '\n') break; } free(p); } rfc822a_free(a); rfc822t_free(t); return (0); }
char *rfc2045_related_start(const struct rfc2045 *p) { const char *cb=rfc2045_getattr( p->content_type_attr, "start"); struct rfc822t *t; struct rfc822a *a; int i; if (!cb || !*cb) return (0); t=rfc822t_alloc_new(cb, 0, NULL); if (!t) { rfc2045_enomem(); return(0); } a=rfc822a_alloc(t); if (!a) { rfc822t_free(t); rfc2045_enomem(); return (0); } for (i=0; i<a->naddrs; i++) if (a->addrs[i].tokens) { char *s=rfc822_getaddr(a, i); rfc822a_free(a); rfc822t_free(t); if (!s) rfc2045_enomem(); return (s); } rfc822a_free(a); rfc822t_free(t); return (0); }
static void newmsg_header_rfc822(const char *label, const char *field, const char *encoded, const char *val, int is_readonly) { int hdrmaxlen=512; const char *p=getarg("HDRMAXLEN"); if (p && (atoi(p) > hdrmaxlen)) hdrmaxlen=atoi(p); printf("<tr><th align=\"right\"><p class=\"new-message-header\">" "<span class=\"new-message-header-%s\">%s</span></p></th>" "<td width=\"6\"> </td>", field, label); printf("<td><input type=\"text\" name=\"%s\" size=\"50\" maxlength=\"%d\"" " class=\"new-message-header-text\" value=\"", field, hdrmaxlen); if (encoded) { struct rfc822t *t=rfc822t_alloc_new(encoded, NULL, NULL); struct rfc822a *a=t ? rfc822a_alloc(t):NULL; if (a) { rfc2047_print_unicodeaddr(a, sqwebmail_content_charset, printc, printsep, NULL); rfc822a_free(a); } if (t) rfc822t_free(t); } else if (val) output_attrencoded(val); printf("\"%s /></td></tr>\n", is_readonly ? " readonly=\"readonly\"":""); }
static struct rfc822t *tokenize(const char *p) { struct rfc822t *tp; int i; char buf[2]; printf("Tokenize: %s\n", p); tp=rfc822t_alloc_new(p, NULL, NULL); if (!tp) exit(0); buf[1]=0; for (i=0; i<tp->ntokens; i++) { buf[0]=tp->tokens[i].token; if (buf[0] == '\0' || buf[0] == '"' || buf[0] == '(') { printf("%s: ", buf[0] == '"' ? "Quote": buf[0] == '(' ? "Comment":"Atom"); fwrite(tp->tokens[i].ptr, tp->tokens[i].len, 1, stdout); printf("\n"); } else printf("Token: %s\n", buf[0] ? buf:"atom"); } return (tp); }
char *newmsg_alladdrs(FILE *fp) { char *headers=NULL; struct rfc822t *t; struct rfc822a *a; char *p, *q; int l, i; if (fp) { char *header, *value; rewind(fp); /* First, combine all the headers into one header. */ while ((header=maildir_readheader(fp, &value, 1)) != 0) { char *newh; if (strcmp(header, "from") && strcmp(header, "to") && strcmp(header, "cc") && strcmp(header, "bcc")) continue; if (headers) { newh=realloc(headers, strlen(headers) +strlen(value)+2); if (!newh) continue; strcat(newh, ","); headers=newh; } else { newh=malloc(strlen(value)+1); if (!newh) continue; *newh=0; headers=newh; } strcat(headers, value); } } /* Now, parse the header, and extract the addresses */ t=rfc822t_alloc_new(headers ? headers:"", NULL, NULL); a= t ? rfc822a_alloc(t):NULL; l=1; for (i=0; i < (a ? a->naddrs:0); i++) { p=rfc822_getaddr(a, i); if (p) { ++l; l +=strlen(p); free(p); } } p=malloc(l); if (p) *p=0; for (i=0; i < (a ? a->naddrs:0); i++) { q=rfc822_getaddr(a, i); if (q) { if (p) { strcat(strcat(p, q), "\n"); } free(q); } } rfc822a_free(a); rfc822t_free(t); free(headers); return (p); }
static void doenva(void (*writefunc)(const char *, size_t), char *s) { struct rfc822t *t; struct rfc822a *a; int i; char *q, *r; if (!s) { (*writefunc)("NIL", 3); return; } t=rfc822t_alloc_new(s, 0, 0); if (!t) { perror("malloc"); exit(0); } a=rfc822a_alloc(t); if (!a) { perror("malloc"); exit(1); } if (a->naddrs == 0) { rfc822a_free(a); rfc822t_free(t); free(s); (*writefunc)("NIL", 3); return; } (*writefunc)("(", 1); for (i=0; i<a->naddrs; i++) { (*writefunc)("(", 1); q=rfc822_display_name_tobuf(a, i, NULL); if (!q) { perror("malloc"); exit(1); } if (a->addrs[i].tokens == 0) { if (strcmp(q, ";") == 0) { (*writefunc)("NIL NIL NIL NIL)", 16); free(q); continue; } r=strrchr(q, ':'); if (r && r[1] == 0) *r=0; (*writefunc)("NIL NIL \"", 9); msgappends(writefunc, q, strlen(q)); (*writefunc)("\" NIL)", 6); free(q); continue; } if (a->addrs[i].name == 0) *q=0; /* rfc822_display_name_tobuf() defaults to addr, ignore. */ doenvs(writefunc, q); (*writefunc)(" NIL \"", 6); /* TODO @domain list */ q=rfc822_gettok(a->addrs[i].tokens); if (!q) { perror("malloc"); exit(1); } r=strrchr(q, '@'); if (r) *r++=0; msgappends(writefunc, q, strlen(q)); (*writefunc)("\" \"", 3); if (r) msgappends(writefunc, r, strlen(r)); (*writefunc)("\")", 2); free(q); } (*writefunc)(")", 1); rfc822a_free(a); rfc822t_free(t); free(s); }
static char *rewrite_from(const char *oldfrom, const char *newuser, const char *newhost, const char *newname) { struct rfc822t *rfct; struct rfc822a *rfca; struct rfc822t *usert, *hostt, *namet; struct rfc822token attoken, **tp; char *p; const char *q; char *gecosname=0; if (!oldfrom) { char *p=courier_malloc( (newuser ? strlen(newuser):0)+ (newhost ? strlen(newhost):0)+4); strcpy(p, "<"); if (newuser) strcat(p, newuser); if (newuser && newhost) strcat(strcat(p, "@"), newhost); strcat(p, ">"); if (newname) { char *q, *r; namet=tokenize_name(newname); q=rfc822_gettok(namet->tokens); rfc822t_free(namet); r=courier_malloc(strlen(p)+strlen(q)+2); strcat(strcat(strcpy(r, q), " "), p); free(p); p=r; free(q); } return (p); } if ((rfct=rfc822t_alloc_new(oldfrom, NULL, NULL)) == 0 || (rfca=rfc822a_alloc(rfct)) == 0) { clog_msg_errno(); return(0); } if ((q=env("MAILNAME")) || (q=env("NAME"))) newname=q; if (!newname && rfca->naddrs == 0) newname=gecosname=get_gecos(); if ((rfca->naddrs == 0 || rfca->addrs[0].tokens == 0) && newuser == 0) { struct passwd *pw=mypwd(); if (pw) newuser=pw->pw_name; } namet=newname ? tokenize_name(newname):0; usert=newuser ? rw_rewrite_tokenize(newuser):0; hostt=newhost ? rw_rewrite_tokenize(newhost):0; if (rfca->naddrs == 0 || rfca->addrs[0].tokens == 0) { struct rfc822addr a; struct rfc822a fakea; if (hostt) { struct rfc822token *t; attoken.token='@'; attoken.next=hostt->tokens; attoken.ptr=0; attoken.len=0; for (t=usert->tokens; t->next; t=t->next) ; t->next=&attoken; } fakea.naddrs=1; fakea.addrs= &a; if (!namet) namet=tokenize_name(""); if (!usert) usert=rw_rewrite_tokenize(""); a.name=namet->tokens; a.tokens=usert->tokens; p=rfc822_getaddrs(&fakea); } else { struct rfc822token *t, *u; rfca->naddrs=1; if (usert) { for (t=rfca->addrs[0].tokens; t; t=t->next) if (t->token == '@') break; for (u=usert->tokens; u->next; u=u->next) ; u->next=t; rfca->addrs[0].tokens=usert->tokens;; } if (hostt && rfca->addrs[0].tokens) { for (tp= &rfca->addrs[0].tokens; *tp; tp= &(*tp)->next) if ( (*tp)->token == '@') break; *tp=&attoken; attoken.token='@'; attoken.next=hostt->tokens; attoken.ptr=0; attoken.len=0; } if (namet) rfca->addrs[0].name=namet->tokens; p=rfc822_getaddrs(rfca); } if (!p) clog_msg_errno(); if (usert) rfc822t_free(usert); if (hostt) rfc822t_free(hostt); if (namet) rfc822t_free(namet); rfc822t_free(rfct); rfc822a_free(rfca); if (gecosname) free(gecosname); return (p); }
static void do_header(struct rfc2045 *p) { struct rfc822t *header; char *t; if (p->headerlen == 0) return; rfc2045_add_buf( &p->header, &p->headersize, &p->headerlen, "", 1); /* 0 terminate */ /* Parse the header line according to RFC822 */ header=rfc822t_alloc_new(p->header, NULL, NULL); if (!header) return; /* Broken header */ if (header->ntokens < 2 || header->tokens[0].token || header->tokens[1].token != ':') { rfc822t_free(header); return; /* Broken header */ } t=lower_paste_token(header, 0); if (t == 0) ; else if (strcmp(t, "mime-version") == 0) { free(t); mime_version(p, header); } else if (strcmp(t, "content-type") == 0) { free(t); content_type(p, header); } else if (strcmp(t, "content-transfer-encoding") == 0) { free(t); content_transfer_encoding(p, header); } else if (strcmp(t, "content-disposition") == 0) { free(t); content_disposition(p, header); } else if (strcmp(t, "content-id") == 0) { free(t); content_id(p, header); } else if (strcmp(t, "content-description") == 0) { free(t); t=strchr(p->header, ':'); if (t) ++t; while (t && isspace((int)(unsigned char)*t)) ++t; content_description(p, t); } else if (strcmp(t, "content-language") == 0) { free(t); t=strchr(p->header, ':'); if (t) ++t; while (t && isspace((int)(unsigned char)*t)) ++t; content_language(p, t); } else if (strcmp(t, "content-base") == 0) { free(t); content_base(p, header); } else if (strcmp(t, "content-location") == 0) { free(t); content_location(p, header); } else if (strcmp(t, "content-md5") == 0) { free(t); t=strchr(p->header, ':'); if (t) ++t; while (t && isspace((int)(unsigned char)*t)) ++t; content_md5(p, t); } else free(t); rfc822t_free(header); }
static void dodel(const char *username, const char *userhome, FILE *c, char *ctl, const char *extension, const char *sender, const char *receipient, const char *defaultext, const char *quota, const char *defaultmail, int recursion_level) { char *ufromline; char *dtline; char *rpline; time_t t; const char *curtime; time(&t); curtime=ctime(&t); if ((ufromline=malloc(strlen(curtime)+strlen(sender)+30))==0|| (dtline=malloc(strlen(receipient)+ sizeof("Delivered-To: "))) == 0 || (rpline=malloc(strlen(sender) + sizeof("Return-Path: <>"))) == 0) { perror("malloc"); exit(EX_TEMPFAIL); } if ( (!ctl || !*ctl) && recursion_level == 0) { const char *p= *defaultmail ? defaultmail:config_defaultdelivery(); if ((ctl=malloc(strlen(p)+1)) == 0) { perror("malloc"); exit(EX_TEMPFAIL); } strcpy(ctl, p); } sprintf(ufromline, "From %s %s", sender, curtime); { char *p; if ((p=strchr(ufromline, '\n')) != 0) *p=0; } strcat(strcpy(dtline, "Delivered-To: "), receipient); strcat(strcat(strcpy(rpline, "Return-Path: <"), sender), ">"); while (*ctl) { if (*ctl == '#' || *ctl == '\n') { while (*ctl) if (*ctl++ == '\n') break; continue; } /* ** The fd hack is needed for BSD, whose C lib doesn't like ** mixing stdio and unistd seek calls. */ if (*ctl == '.' || *ctl == '/') { const char *filename=ctl; int fd_hack=dup(fileno(stdin)); FILE *fp_hack; if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 || (fp_hack=fdopen(fd_hack, "r")) == NULL) { perror("dup"); exit(EX_TEMPFAIL); } while (*ctl) { if (*ctl == '/' && (ctl[1] == '\n' || ctl[1] == 0)) *ctl=0; /* Strip trailing / */ if (*ctl == '\n') { *ctl++='\0'; break; } ++ctl; } if (savemessage(extension, sender, receipient, fp_hack, filename, ufromline, dtline, rpline, quota)) exit(EX_TEMPFAIL); fclose(fp_hack); close(fd_hack); continue; } if (*ctl == '|') { const char *command=++ctl; int rc; int fd_hack=dup(fileno(stdin)); FILE *fp_hack; if (fd_hack < 0 || lseek(fd_hack, 0L, SEEK_SET) < 0 || (fp_hack=fdopen(fd_hack, "r")) == NULL) { perror("dup"); exit(EX_TEMPFAIL); } ctl=skip_eol(ctl, 0); while (*command == ' ' || *command == '\t') ++command; rc=docommand(extension, sender, receipient, defaultext, fp_hack, username, userhome, command, dtline, rpline, ufromline, quota, defaultmail, recursion_level); if (rc) exit(rc); fclose(fp_hack); close(fd_hack); continue; } /* Forwarding instructions, parse RFC822 addresses */ if (*ctl == '&' || *ctl == '!') ++ctl; /* Legacy */ { const char *addresses=ctl; struct rfc822t *tokens; struct rfc822a *addrlist; int n; ctl=skip_eol(ctl, 1); if ((tokens=rfc822t_alloc_new(addresses, NULL, NULL)) == 0 || (addrlist=rfc822a_alloc(tokens)) == 0) { perror("malloc"); exit(EX_TEMPFAIL); } for (n=0; n<addrlist->naddrs; ++n) { char *p; if (addrlist->addrs[n].tokens == NULL) continue; p=rfc822_display_addr_tobuf(addrlist, n, NULL); if (!p) { perror(addresses); exit(EX_TEMPFAIL); } printf("%s\n", p); free(p); } rfc822a_free(addrlist); rfc822t_free(tokens); fflush(stdout); } } free(rpline); free(dtline); free(ufromline); }
static void readforward(FILE *f, int n) { char buf[BUFSIZ]; char *p; struct rfc822t *t; struct rfc822a *a; int i; char *sep; while (fgets(buf, sizeof(buf), f)) { p=strchr(buf, '\n'); if (p) *p=0; p=buf; while (*p && isspace((int)(unsigned char)*p)) ++p; if (strncmp(p, ":include:", 9) == 0) { FILE *g; if (n > 10) { fprintf(stderr, "dotforward: too many :include files.\n"); exit(EX_NOUSER); } p += 9; while (*p && isspace((int)(unsigned char)*p)) ++p; if (!*p) continue; g=fopen(p, "r"); if (!g) { perror(p); exit(EX_NOUSER); } readforward(g, n+1); fclose(g); continue; } if (*p == '|' || *p == '/' || *p == '.') { printf("%s\n", p); continue; } t=rfc822t_alloc_new(p, NULL, NULL); if (!t || !(a=rfc822a_alloc(t))) { perror("malloc"); exit(EX_NOUSER); } for (i=0; i<a->naddrs; i++) { if (a->addrs[i].tokens && a->addrs[i].tokens->token == '"' && a->addrs[i].tokens->next == NULL) a->addrs[i].tokens->token=0; p=rfc822_getaddr(a, i); if (!p) { perror("malloc"); exit(EX_NOUSER); } if (*p == '|' || *p == '/') { printf("%s\n", p); } free(p); } sep=0; for (i=0; i<a->naddrs; i++) { char *q, *r; struct delivered_to *s; char *t; char *orig; p=rfc822_getaddr(a, i); if (!p) { perror("malloc"); exit(EX_NOUSER); } if (*p == '|' || *p == '/' || *p == '.') { free(p); continue; } q=p; if (*q == '\\') ++q; r=strchr(q, '@'); if (!r || config_islocal(r+1, 0)) locallower(q); domainlower(q); t=0; orig=q; if (strchr(q, '@') == 0) { t=malloc(strlen(q)+1+strlen(myaddr)); /* overkill, yeah */ if (!t) { perror("malloc"); exit(EX_NOUSER); } strcat(strcpy(t, q), strchr(myaddr, '@')); q=t; } if (strcmp(myaddr, q) == 0) { exit_code=0; free(p); if (t) free(t); continue; } for (s=delivtolist; s; s=s->next) { if (strcmp(s->addr, q) == 0) break; } if (!s) { if (sep) printf("%s", sep); else printf("!"); sep=", "; printf("%s", orig); } free(p); if (t) free(t); } if (sep) printf("\n"); rfc822a_free(a); rfc822t_free(t); } }