void reset(void) { if(rejectcheck()) return; listfree(&rcvers); listfree(&senders); if(filterstate != DIALUP){ logged = 0; filterstate = ACCEPT; } reply("250 2.0.0 ok\r\n"); }
void treefree(ast_st *past) { if(past == NULL) { return; } switch(past->nodetype) { case '+': case '-': case '*': case '/': treefree(past->r); case 'M': treefree(past->l); break; case 'S': { symbol_st *tmpsym = NULL; tmpsym = ((name_st *)past)->sym; if(tmpsym->func) treefree(tmpsym->func); if(tmpsym->plist) listfree(tmpsym->plist); free(tmpsym->name); break; } default: //printf("free error!\n"); break; } free(past); }
/* Locate enums whose name is a prefix of ident and contains the suffix as an enum const and capture that enum constant. */ static List* findecmatches(char* ident) { List* matches = listnew(); int i; for(i=0;i<listlength(typdefs);i++) { int len; Symbol* ec; Symbol* en = (Symbol*)listget(typdefs,i); if(en->subclass != NC_ENUM) continue; /* First, assume that the ident is the econst name only */ ec = checkeconst(en,ident); if(ec != NULL) listpush(matches,ec); /* Second, do the prefix check */ len = strlen(en->name); if(strncmp(ident,en->name,len) == 0) { Symbol *ec; /* Find the matching ec constant, if any */ if(*(ident+len) != '.') continue; ec = checkeconst(en,ident+len+1); /* +1 for the dot */ if(ec != NULL) listpush(matches,ec); } } if(listlength(matches) == 0) { listfree(matches); matches = NULL; } return matches; }
void dodef(symbol_st *name, param_st *plist, ast_st *func) { if(name->func != NULL) treefree(name->func); if(name->plist != NULL) listfree(name->plist); name->func = func; name->plist = plist; }
void fileclose(File *f) { Strclose(&f->name); bufclose(&f->Buffer); bufclose(&f->delta); bufclose(&f->epsilon); if(f->rasp) listfree(f->rasp); free(f); }
int listfreeall(List* l) { if(l) { int i; for(i=0;i<listlength(l);i++) { void* elem = listget(l,i); if(elem != NULL) free(elem); } } return listfree(l); }
static List* ecsearchgrp(Symbol* grp, List* candidates) { List* matches = listnew(); int i,j; /* do the intersection of grp subnodes and candidates */ for(i=0;i<listlength(grp->subnodes);i++) { Symbol* sub= (Symbol*)listget(grp->subnodes,i); if(sub->subclass != NC_ENUM) continue; for(j=0;j<listlength(candidates);j++) { Symbol* ec = (Symbol*)listget(candidates,j); if(ec->container == sub) listpush(matches,ec); } } if(listlength(matches) == 0) { listfree(matches); matches = NULL; } return matches; }
void data(void) { int status, nbytes; char *cp, *ep; char errx[ERRMAX]; Link *l; String *cmd, *err; if(rejectcheck()) return; if(senders.last == 0){ reply("503 2.5.2 Data without MAIL FROM:\r\n"); rejectcount++; return; } if(rcvers.last == 0){ reply("503 2.5.2 Data without RCPT TO:\r\n"); rejectcount++; return; } if(!trusted && sendermxcheck()){ rerrstr(errx, sizeof errx); if(strncmp(errx, "rejected:", 9) == 0) reply("554 5.7.1 %s\r\n", errx); else reply("450 4.7.0 %s\r\n", errx); for(l=rcvers.first; l; l=l->next) syslog(0, "smtpd", "[%s/%s] %s -> %s sendercheck: %s", him, nci->rsys, s_to_c(senders.first->p), s_to_c(l->p), errx); rejectcount++; return; } cmd = startcmd(); if(cmd == 0) return; reply("354 Input message; end with <CRLF>.<CRLF>\r\n"); if(debug){ seek(2, 0, 2); stamp(); fprint(2, "# sent 354; accepting DATA %s\n", thedate()); } /* * allow 145 more minutes to move the data */ alarm(145*60*1000); status = pipemsg(&nbytes); /* * read any error messages */ err = s_new(); if (debug) { stamp(); fprint(2, "waiting for upas/send to close stderr\n"); } while(s_read_line(pp->std[2]->fp, err)) ; alarm(0); atnotify(catchalarm, 0); if (debug) { stamp(); fprint(2, "waiting for upas/send to exit\n"); } status |= proc_wait(pp); if(debug){ seek(2, 0, 2); stamp(); fprint(2, "# %d upas/send status %#ux at %s\n", getpid(), status, thedate()); if(*s_to_c(err)) fprint(2, "# %d error %s\n", getpid(), s_to_c(err)); } /* * if process terminated abnormally, send back error message */ if(status){ int code; char *ecode; if(strstr(s_to_c(err), "mail refused")){ syslog(0, "smtpd", "++[%s/%s] %s %s refused: %s", him, nci->rsys, s_to_c(senders.first->p), s_to_c(cmd), firstline(s_to_c(err))); code = 554; ecode = "5.0.0"; } else { syslog(0, "smtpd", "++[%s/%s] %s %s %s%s%sreturned %#q %s", him, nci->rsys, s_to_c(senders.first->p), s_to_c(cmd), piperror? "error during pipemsg: ": "", piperror? piperror: "", piperror? "; ": "", pp->waitmsg->msg, firstline(s_to_c(err))); code = 450; ecode = "4.0.0"; } for(cp = s_to_c(err); ep = strchr(cp, '\n'); cp = ep){ *ep++ = 0; reply("%d-%s %s\r\n", code, ecode, cp); } reply("%d %s mail process terminated abnormally\r\n", code, ecode); } else { /* * if a message appeared on stderr, despite good status, * log it. this can happen if rewrite.in contains a bad * r.e., for example. */ if(*s_to_c(err)) syslog(0, "smtpd", "%s returned good status, but said: %s", s_to_c(mailer), s_to_c(err)); if(filterstate == BLOCKED) reply("554 5.7.1 we believe this is spam. " "we don't accept it.\r\n"); else if(filterstate == DELAY) reply("450 4.3.0 There will be a delay in delivery " "of this message.\r\n"); else { reply("250 2.5.0 sent\r\n"); logcall(nbytes); if(debug){ seek(2, 0, 2); stamp(); fprint(2, "# %d sent 250 reply %s\n", getpid(), thedate()); } } } proc_free(pp); pp = 0; s_free(cmd); s_free(err); listfree(&senders); listfree(&rcvers); }
/* If we have an enum-valued group attribute, then we need to do extra work to find the containing enum type */ static Symbol* locateenumtype(Symbol* refsym, Symbol* parent, NCConstant* con) { Symbol* match = NULL; List* grpmatches; /* Locate all possible matching enum constant definitions */ List* candidates = findecmatches(refsym->name); if(candidates == NULL) { semerror(con->lineno,"Undefined enum or enum constant reference: %s",refsym->name); return NULL; } /* One hopes that 99% of the time, the match is unique */ if(listlength(candidates) == 1) { match = listget(candidates,0); goto done; } /* If this ref has a specified group prefix, then find that group and search only within it for matches to the candidates */ if(refsym->is_prefixed && refsym->prefix != NULL) { parent = lookupgroup(refsym->prefix); if(parent == NULL) { semerror(con->lineno,"Undefined group reference: ",fullname(refsym)); goto done; } /* Search this group only for matches */ grpmatches = ecsearchgrp(parent,candidates); switch (listlength(grpmatches)) { case 0: semerror(con->lineno,"Undefined enum or enum constant reference: ",refsym->name); listfree(grpmatches); goto done; case 1: break; default: semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym)); } match = listget(grpmatches,0); listfree(grpmatches); goto done; } /* Sigh, we have to search up the tree to see if any of our candidates are there */ assert(parent == NULL || parent->objectclass == NC_GRP); while(parent != NULL && match == NULL) { grpmatches = ecsearchgrp(parent,candidates); switch (listlength(grpmatches)) { case 0: break; case 1: match = listget(grpmatches,0); break; default: semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym)); match = listget(grpmatches,0); break; } listfree(grpmatches); } if(match != NULL) goto done; /* Not unique and not in the parent tree, so complains and pick the first candidate */ semerror(con->lineno,"Ambiguous enum constant reference: %s", fullname(refsym)); match = (Symbol*)listget(candidates,0); done: listfree(candidates); return match; }
/* 3. mark types that use vlen*/ static void processtypes(void) { unsigned long i,j; int keep,added; List* sorted = listnew(); /* hold re-ordered type set*/ /* Prime the walk by capturing the set*/ /* of types that are dependent on primitive types*/ /* e.g. uint vlen(*) or primitive types*/ for(i=0;i<listlength(typdefs);i++) { Symbol* sym = (Symbol*)listget(typdefs,i); keep=0; switch (sym->subclass) { case NC_PRIM: /*ignore pre-defined primitive types*/ sym->touched=1; break; case NC_OPAQUE: case NC_ENUM: keep=1; break; case NC_VLEN: /* keep if its basetype is primitive*/ if(sym->typ.basetype->subclass == NC_PRIM) keep=1; break; case NC_COMPOUND: /* keep if all fields are primitive*/ keep=1; /*assume all fields are primitive*/ for(j=0;j<listlength(sym->subnodes);j++) { Symbol* field = (Symbol*)listget(sym->subnodes,j); ASSERT(field->subclass == NC_FIELD); if(field->typ.basetype->subclass != NC_PRIM) {keep=0;break;} } break; default: break;/* ignore*/ } if(keep) { sym->touched = 1; listpush(sorted,(void*)sym); } } /* 2. repeated walk to collect level i types*/ do { added=0; for(i=0;i<listlength(typdefs);i++) { Symbol* sym = (Symbol*)listget(typdefs,i); if(sym->touched) continue; /* ignore already processed types*/ keep=0; /* assume not addable yet.*/ switch (sym->subclass) { case NC_PRIM: case NC_OPAQUE: case NC_ENUM: PANIC("type re-touched"); /* should never happen*/ break; case NC_VLEN: /* keep if its basetype is already processed*/ if(sym->typ.basetype->touched) keep=1; break; case NC_COMPOUND: /* keep if all fields are processed*/ keep=1; /*assume all fields are touched*/ for(j=0;j<listlength(sym->subnodes);j++) { Symbol* field = (Symbol*)listget(sym->subnodes,j); ASSERT(field->subclass == NC_FIELD); if(!field->typ.basetype->touched) {keep=1;break;} } break; default: break; } if(keep) { listpush(sorted,(void*)sym); sym->touched = 1; added++; } } } while(added > 0); /* Any untouched type => circular dependency*/ for(i=0;i<listlength(typdefs);i++) { Symbol* tsym = (Symbol*)listget(typdefs,i); if(tsym->touched) continue; semerror(tsym->lineno,"Circular type dependency for type: %s",fullname(tsym)); } listfree(typdefs); typdefs = sorted; /* fill in type typecodes*/ for(i=0;i<listlength(typdefs);i++) { Symbol* sym = (Symbol*)listget(typdefs,i); if(sym->typ.basetype != NULL && sym->typ.typecode == NC_NAT) sym->typ.typecode = sym->typ.basetype->typ.typecode; } /* Identify types containing vlens */ for(i=0;i<listlength(typdefs);i++) { Symbol* tsym = (Symbol*)listget(typdefs,i); tagvlentypes(tsym); } }