int main() { struct rfc822t *t1, *t2, *t3, *t4; struct rfc822a *a1, *a2, *a3, *a4; t1=tokenize("[email protected] (Nobody (is) here\\) right)"); t2=tokenize("Distribution list: [email protected] [email protected]"); t3=tokenize("Mr Nobody <*****@*****.**>, Mr. Nobody <*****@*****.**>"); t4=tokenize("[email protected], <*****@*****.**>, Mr. Nobody <*****@*****.**>"); a1=doaddr(t1); a2=doaddr(t2); a3=doaddr(t3); a4=doaddr(t4); rfc822a_free(a4); rfc822a_free(a3); rfc822a_free(a2); rfc822a_free(a1); rfc822t_free(t4); rfc822t_free(t3); rfc822t_free(t2); rfc822t_free(t1); return (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); }
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); }
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); }
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); }
drvinfo *msgq::getdelinfo(struct rfc822token *sendert, const char *receipient, std::string &host, std::string &addr, std::string &errmsg) { struct getdelinfo_struct gdis(0, host, addr); struct rw_info rwi; struct rfc822t *rfcp=rw_rewrite_tokenize(receipient); rw_info_init(&rwi, rfcp->tokens, gdi_err_func); rwi.sender=sendert; rwi.mode=RW_OUTPUT|RW_ENVRECIPIENT; rwi.udata= (void *)&gdis; rw_searchdel(&rwi, &found_module); rfc822t_free(rfcp); if (!gdis.drvinfop && gdis.errmsg.size() == 0) gdis.errmsg="550 User unknown."; errmsg=gdis.errmsg; return (gdis.drvinfop); }
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\"":""); }
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); }
int msgq::queuescan3(std::string subdir, std::string name, const char *isnewmsg) { struct ctlfile ctlinfo; ino_t inum; time_t deltime, delsendtime; const char *p=name.c_str(); struct stat stat_buf; ++p; inum=strtoino(p); while (isdigit(*p)) p++; ++p; deltime=strtotime(p); name= subdir + '/' + name; if (ctlfile_openfn(name.c_str(), &ctlinfo, 0, 1)) { if (errno) { clog_msg_start_err(); clog_msg_str("Cannot read "); clog_msg_str(name.c_str()); clog_msg_send(); clog_msg_prerrno(); } return (0); } delsendtime=deltime; if (flushtime && ctlinfo.mtime < flushtime && flushtime < deltime) delsendtime=flushtime; if (!queuefree) { msgq *p; // // msgq array is full. See if we can remove the last message from the // pending queue. p=queuetail; if (p && p->nextsenddel > delsendtime) { #if 0 clog_msg_start_info(); clog_msg_str("Removing "); clog_msg_uint(p->msgnum); clog_msg_str(" to make room for this message."); clog_msg_send(); #endif p->removewq(); p->removeq(); } } msgq *newq=queuefree; if (!newq) { ctlfile_close(&ctlinfo); if (queuefill && nextqueuefill == 0) { nextqueuefill=current_time + queuefill; } return (1); } const char *cn=qmsgsctlname(inum); if ( stat(cn, &stat_buf) == -1 ) { unlink(name.c_str()); unlink(qmsgsdatname(inum)); unlink(cn); ctlfile_close(&ctlinfo); return (0); } #if 0 clog_msg_start_info(); clog_msg_str("Adding "); clog_msg_uint(inum); clog_msg_str(" to queue."); clog_msg_send(); #endif queuefree=newq->next; ++queuedelivering; ino_t hashbucket=inum % queuehashfirst.size(); if (queuehashfirst[hashbucket]) queuehashfirst[hashbucket]->prevhash=newq; else queuehashlast[hashbucket]=newq; newq->nexthash=queuehashfirst[hashbucket]; newq->prevhash=0; queuehashfirst[hashbucket]=newq; newq->nksize= (unsigned long)stat_buf.st_size; ctlinfo.starttime=stat_buf.st_mtime; int k=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_MSGID); newq->msgid= k < 0 ? "": ctlinfo.lines[k]+1; newq->msgnum=inum; newq->nextdel=deltime; newq->nextsenddel=delsendtime; newq->rcptinfo_list.resize(0); newq->rcptcount=0; newq->cancelled=ctlinfo.cancelled; if (isnewmsg) { int auth; clog_msg_start_info(); clog_msg_str("newmsg,id="); logmsgid(newq); auth=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_AUTHNAME); if (auth >= 0) { clog_msg_str(", auth="); clog_msg_str(ctlinfo.lines[auth]+1); } int m=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_FROMMTA); if (m >= 0) { clog_msg_str(": "); clog_msg_str(ctlinfo.lines[m]+1); } clog_msg_send(); } unsigned i, j; std::string host, addr; k=ctlfile_searchfirst(&ctlinfo, COMCTLFILE_SENDER); struct rfc822t *sendert=rw_rewrite_tokenize(k < 0 ? "":ctlinfo.lines[k]+1); std::string errmsg; for (i=0; i<ctlinfo.nreceipients; i++) { for (j=0; ctlinfo.lines[j]; j++) { switch (ctlinfo.lines[j][0]) { case COMCTLFILE_DELSUCCESS: case COMCTLFILE_DELFAIL: if ((unsigned)atoi(ctlinfo.lines[j]+1) == i) break; // This one has been delivered default: continue; } break; } if (ctlinfo.lines[j]) continue; drvinfo *module=getdelinfo(sendert->tokens, ctlinfo.receipients[i], host, addr, errmsg); if (!module) { ctlfile_append_reply(&ctlinfo, i, errmsg.c_str(), SMTPREPLY_TYPE(errmsg.c_str()), 0); continue; } /* Check if it's time to move the message to a backup relay */ if (backup_relay_driver && ctlfile_searchfirst(&ctlinfo, COMCTLFILE_WARNINGSENT) >= 0 && strcmp(module->module->name, backup_relay_driver->module->name) == 0) { // module=backup_relay_driver; host=backup_relay; } /* Group all recipients for the same driver and host together */ for (j=0; j<newq->rcptcount; j++) if (strcmp(module->module->name, newq->rcptinfo_list[j].delmodule-> module->name) == 0 && newq->rcptinfo_list[j].delhost == host && newq->rcptinfo_list[j].addresses.size() < module->maxrcpt ) break; if (j == newq->rcptcount) { #if 0 clog_msg_start_info(); clog_msg_str("id="); logmsgid(newq); clog_msg_str(",new rcpt list - module="); clog_msg_str(module->module->name); clog_msg_str(", host="); clog_msg_str(host); clog_msg_send(); #endif newq->rcptinfo_list.resize(++newq->rcptcount); struct rw_info_rewrite rwir; struct rw_info rwi; rwir.buf=0; rwir.errmsg=0; rw_info_init(&rwi, sendert->tokens, rw_err_func); rwi.sender=0; rwi.mode=RW_OUTPUT|RW_ENVSENDER; rwi.udata= (void *)&rwir; rw_rewrite_module(module->module, &rwi, rw_rewrite_chksyn_print); char *address=((struct rw_info_rewrite *)rwi.udata)->buf; char *errmsg= ((struct rw_info_rewrite *)rwi.udata)->errmsg; if (!address) { ctlfile_append_reply(&ctlinfo, i, errmsg, SMTPREPLY_TYPE(errmsg), 0); newq->rcptinfo_list.resize(--newq->rcptcount); free(errmsg); continue; } if (errmsg) free(errmsg); newq->rcptinfo_list[j].init(newq, module, host, address); free(address); } #if 0 clog_msg_start_info(); clog_msg_str("id="); logmsgid(newq); clog_msg_str(",module="); clog_msg_str(module->module->name); clog_msg_str(", host="); clog_msg_str(host); clog_msg_str(", addr=<"); clog_msg_str(addr); clog_msg_str(">"); clog_msg_send(); #endif newq->rcptinfo_list[j].addresses.push_back(addr); newq->rcptinfo_list[j].addressesidx.push_back(i); } rfc822t_free(sendert); ctlfile_close(&ctlinfo); if (newq->nextsenddel <= current_time || /* ** If there are no more recipients, we want to call done() via ** start_message. HOWEVER, if DSN injection FAILED, we want to respect ** the rescheduled delivery attempt time. We can detect that if isnewmsg == 0 */ (newq->rcptinfo_list.size() == 0 && isnewmsg)) { newq->start_message(); return (0); } msgq *qp, *qprev; for (qprev=queuetail, qp=0; qprev; qp=qprev, qprev=qp->prev) if (qprev->nextsenddel < newq->nextsenddel) break; newq->next=qp; newq->prev=qprev; if (qprev) qprev->next=newq; else queuehead=newq; if (qp) qp->prev=newq; else queuetail=newq; ++queuewaiting; return (0); }
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); } }
struct imap_refmsg *rfc822_threadmsg(struct imap_refmsgtable *mt, const char *msgidhdr, const char *refhdr, const char *subjheader, const char *dateheader, unsigned long seqnum) { struct rfc822t *t; struct rfc822a *a; struct imap_refmsg *m; char *msgid_s; t=rfc822t_alloc(msgidhdr ? msgidhdr:"", 0); if (!t) return (0); a=rfc822a_alloc(t); if (!a) { rfc822t_free(t); return (0); } msgid_s=a->naddrs > 0 ? rfc822_getaddr(a, 0):strdup(""); rfc822a_free(a); rfc822t_free(t); if (!msgid_s) return (0); t=rfc822t_alloc(refhdr ? refhdr:"", 0); if (!t) { free(msgid_s); return (0); } a=rfc822a_alloc(t); if (!a) { rfc822t_free(t); free(msgid_s); return (0); } m=dorefcreate(mt, msgid_s, a); rfc822a_free(a); rfc822t_free(t); free(msgid_s); if (!m) return (0); if (subjheader && (m->subj=strdup(subjheader)) == 0) return (0); /* Cleanup in rfc822_threadfree() */ m->timestamp=dateheader ? rfc822_parsedt(dateheader):0; m->seqnum=seqnum; return (m); }