static int checkindir(long a, Dentry *d, long qpath) { Iobuf *p; int i, dmod; dmod = touch(a); p = xtag(a, Tind1, qpath); if(!p) return dmod; for(i=0; i<INDPERBUF; i++) { a = ((long*)p->iobuf)[i]; if(!a) continue; if(amark(a)) { if(flags & Cbad) { ((long*)p->iobuf)[i] = 0; p->flags |= Bmod; } continue; } if(d->mode & DDIR) dmod += checkdir(a, qpath); else if(flags & Crdall) xread(a, qpath); } putbuf(p); return dmod; }
static void xread(long a, long qpath) { Iobuf *p; p = xtag(a, Tfile, qpath); if(p) putbuf(p); }
static void ckfreelist(Superb *sb) { long a, lo, hi; int n, i; Iobuf *p; Fbuf *fb; strcpy(name, "free list"); cprint("check %s\n", name); fb = &sb->fbuf; a = sbaddr; p = 0; lo = 0; hi = 0; for(;;) { n = fb->nfree; if(n < 0 || n > FEPERBUF) { cprint("check: nfree bad %ld\n", a); break; } for(i=1; i<n; i++) { a = fb->free[i]; if(a && !fmark(a)) { if(!lo || lo > a) lo = a; if(!hi || hi < a) hi = a; } } a = fb->free[0]; if(!a) break; if(fmark(a)) break; if(!lo || lo > a) lo = a; if(!hi || hi < a) hi = a; if(p) putbuf(p); p = xtag(a, Tfree, QPNONE); if(!p) break; fb = (Fbuf*)p->iobuf; } if(p) putbuf(p); cprint("lo = %ld; hi = %ld\n", lo, hi); }
static Dentry* maked(long a, int s, long qpath) { Iobuf *p; Dentry *d, *d1; p = xtag(a, Tdir, qpath); if(!p) return 0; d = getdir(p, s); d1 = dalloc(sizeof(Dentry)); memmove(d1, d, sizeof(Dentry)); putbuf(p); return d1; }
static int record_select(int nfield, char const *field[], void* vxml) /* * Receive fields from domain selection query. These must be: * ip [0], count [1], dispo [2], d_dkim [3], d_spf [4], reason [5], domain [6], * spf [7], spf_result [8], spf_helo [9], spf_result [10], and * dkim [11], dkim_result [12] (repeated any number of times, NULL values skipped) */ { if (nfield < 10) { (*do_log)(LOG_ERR, "only %d record field(s)%s", nfield, bailout); return -1; } xml_tree *xml = vxml; stag(xml, "record"); stag(xml, "row"); xtag(xml, "source_ip", field[0]); xtag(xml, "count", field[1]); stag(xml, "policy_evaluated"); xtag(xml, "disposition", field[2]); xtag(xml, "dkim", field[3]); xtag(xml, "spf", field[4]); // reason, if given, is type + [space comment] if (field[5] && strcmp(field[5], "none") != 0) { stag(xml, "reason"); char const *c = field[5]; int ch; while (isalnum(ch = *(unsigned char*)c) || ch == '_') ++c; xtagn(xml, "type", field[5], c - field[5]); if (isspace(ch)) xtag(xml, "comment", c+1); etag(xml); // reason } etag(xml); // policy evaluated etag(xml); // row stag(xml, "identifiers"); xtag(xml, "header_from", field[6]); etag(xml); stag(xml, "auth_results"); for (int i = 11; i+1 < nfield; i += 2) if (field[i] && field[i+1]) { stag(xml, "dkim"); xtag(xml, "domain", field[i]); xtag(xml, "result", field[i+1]); etag(xml); // dkim } stag(xml, "spf"); if (field[7] && field[8] && field[9] && field[10]) { bool pass8 = strcmp(field[8], "pass") == 0, pass10 = strcmp(field[10], "pass") == 0; if (pass8 == pass10) { // if both or neither are pass, output helo only if // it is better aligned than mfrom if (field[6] && is_parent_domain_of(field[6], field[9]) && !is_parent_domain_of(field[6], field[7])) field[7] = NULL; } else if (pass10) field[7] = NULL; } if (field[7] && field[8]) { xtag(xml, "domain", field[7]); xtag(xml, "result", field[8]); xtag(xml, "scope", "mfrom"); } else if (field[9] && field[10]) { xtag(xml, "domain", field[9]); xtag(xml, "result", field[10]); xtag(xml, "scope", "helo"); } else { xtag(xml, "domain", ""); xtag(xml, "result", "none"); } etag(xml); // spf etag(xml); // auth_results etag(xml); // record return xml_flush(xml, 0); }
void check(Filsys *fs, long flag) { Iobuf *p; Superb *sb; Dentry *d; long raddr; long nqid; wlock(&mainlock); dev = fs->dev; flags = flag; fence = fencebase; sizname = 4000; name = zalloc(sizname); sizname -= NAMELEN+10; /* for safety */ sbaddr = superaddr(dev); raddr = getraddr(dev); p = xtag(sbaddr, Tsuper, QPSUPER); if(!p){ cprint("bad superblock\n"); goto out; } sb = (Superb*)p->iobuf; fstart = 1; fsize = sb->fsize; sizabits = (fsize-fstart + 7)/8; abits = zalloc(sizabits); nqid = sb->qidgen+100; /* not as much of a botch */ if(nqid > 1024*1024*8) nqid = 1024*1024*8; if(nqid < 64*1024) nqid = 64*1024; sizqbits = (nqid+7)/8; qbits = zalloc(sizqbits); mod = 0; nfree = 0; nfdup = 0; nused = 0; nbad = 0; ndup = 0; nqbad = 0; depth = 0; maxdepth = 0; if(flags & Ctouch) { oldblock = fsize/DSIZE; oldblock *= DSIZE; if(oldblock < 0) oldblock = 0; cprint("oldblock = %ld\n", oldblock); } if(amark(sbaddr)) {} if(cwflag) { if(amark(sb->roraddr)) {} if(amark(sb->next)) {} } if(!(flags & Cquiet)) cprint("checking file system: %s\n", fs->name); nfiles = 0; maxq = 0; d = maked(raddr, 0, QPROOT); if(d) { if(amark(raddr)) {} if(fsck(d)) modd(raddr, 0, d); depth--; fence -= sizeof(Dentry); if(depth) cprint("depth not zero on return\n"); } if(flags & Cfree) { mkfreelist(sb); sb->qidgen = maxq; settag(p, Tsuper, QPNONE); } if(sb->qidgen < maxq) cprint("qid generator low path=%ld maxq=%ld\n", sb->qidgen, maxq); if(!(flags & Cfree)) ckfreelist(sb); if(mod) { cprint("file system was modified\n"); settag(p, Tsuper, QPNONE); } if(!(flags & Cquiet)){ cprint("%8ld files\n", nfiles); cprint("%8ld blocks in the file system\n", fsize-fstart); cprint("%8ld used blocks\n", nused); cprint("%8ld free blocks\n", sb->tfree); } if(!(flags & Cfree)){ if(nfree != sb->tfree) cprint("%8ld free blocks found\n", nfree); if(nfdup) cprint("%8ld blocks duplicated in the free list\n", nfdup); if(fsize-fstart-nused-nfree) cprint("%8ld missing blocks\n", fsize-fstart-nused-nfree); } if(ndup) cprint("%8ld address duplications\n", ndup); if(nbad) cprint("%8ld bad block addresses\n", nbad); if(nqbad) cprint("%8ld bad qids\n", nqbad); if(!(flags & Cquiet)) cprint("%8ld maximum qid path\n", maxq); missing(); out: if(p) putbuf(p); free(abits); free(name); free(qbits); wunlock(&mainlock); }
static int fsck(Dentry *d) { char *s; Rune r; Iobuf *p; int l, i, ns, dmod; long a, qpath; depth++; if(depth >= maxdepth){ maxdepth = depth; if(maxdepth >= MAXDEPTH){ cprint("max depth exceeded: %s\n", name); return 0; } } dmod = 0; if(!(d->mode & DALLOC)) return 0; nfiles++; ns = strlen(name); i = strlen(d->name); if(i >= NAMELEN){ d->name[NAMELEN-1] = 0; cprint("%s->name (%s) not terminated\n", name, d->name); return 0; } ns += i; if(ns >= sizname){ cprint("%s->name (%s) name too large\n", name, d->name); return 0; } for (s = d->name; *s; s += l){ l = chartorune(&r, s); if (r == Runeerror) for (i = 0; i < l; i++){ s[i] = '_'; cprint("%s->name (%s) bad UTF\n", name, d->name); dmod++; } } strcat(name, d->name); if(d->mode & DDIR){ if(ns > 1) strcat(name, "/"); if(flags & Cpdir) cprint("%s\n", name); } else if(flags & Cpfile) cprint("%s\n", name); qpath = d->qid.path & ~QPDIR; qmark(qpath); if(qpath > maxq) maxq = qpath; for(i=0; i<NDBLOCK; i++) { a = d->dblock[i]; if(!a) continue; if(amark(a)) { d->dblock[i] = 0; dmod++; continue; } if(d->mode & DDIR) dmod += checkdir(a, qpath); else if(flags & Crdall) xread(a, qpath); } a = d->iblock; if(a && amark(a)) { d->iblock = 0; dmod++; } else if(a) dmod += checkindir(a, d, qpath); a = d->diblock; if(a && amark(a)) { d->diblock = 0; return dmod + 1; } dmod += touch(a); if(p = xtag(a, Tind2, qpath)){ for(i=0; i<INDPERBUF; i++){ a = ((long*)p->iobuf)[i]; if(!a) continue; if(amark(a)) { if(flags & Cbad) { ((long*)p->iobuf)[i] = 0; p->flags |= Bmod; } continue; } dmod += checkindir(a, d, qpath); } putbuf(p); } return dmod; }