Exemple #1
0
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;
}
Exemple #2
0
static
void
xread(long a, long qpath)
{
	Iobuf *p;

	p = xtag(a, Tfile, qpath);
	if(p)
		putbuf(p);
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
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);
}
Exemple #7
0
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;
}