Esempio n. 1
0
static int
fixedopen(Dssfile_t* file, Dssdisc_t* disc)
{
	if (file->flags & DSS_FILE_READ)
	{
		if (!sfreserve(file->io, file->skip, 0))
		{
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "header read error");
			return -1;
		}
		if (!(file->data = (void*)vmnewof(file->dss->vm, 0, State_t, 1, 0)))
		{
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
			return -1;
		}
		((State_t*)file->data)->swap = file->ident;
	}
	else if (!(file->flags & DSS_FILE_APPEND))
	{
		Fixedheader_t	hdr;

		memset(&hdr, 0, sizeof(hdr));
		hdr.magic.magic = MAGICID;
		strcpy(hdr.magic.name, MAGIC_NAME);
		strcpy(hdr.magic.type, MAGIC_TYPE);
		hdr.magic.version = MAGIC_VERSION;
		hdr.magic.size = sizeof(Netflow_t);
		sfwrite(file->io, &hdr, sizeof(hdr));
	}
	return 0;
}
Esempio n. 2
0
static int
textfopen(Dssfile_t* file, Dssdisc_t* disc)
{
	if (!(file->data = vmnewof(file->dss->vm, 0, Cxvalue_t, ((Text_t*)file->dss->meth->data)->vars, 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	return 0;
}
Esempio n. 3
0
static int
pstat_init(Pss_t* pss)
{
	register State_t*	state;

	if (!(state = vmnewof(pss->vm, 0, State_t, 1, 0)))
	{
		if (pss->disc->errorf)
			(*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	pss->data = state;
	return 1;
}
Esempio n. 4
0
static int
tableopen(Dssfile_t* file, Dssdisc_t* disc)
{
	Tablestate_t*	state;

	if (!(state = vmnewof(file->dss->vm, 0, Tablestate_t, 1, 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	state->route[0].bits = -1;
	state->v6 = file->caller == file;
	file->data = (void*)state;
	return 0;
}
Esempio n. 5
0
static int
dumpfopen(Dssfile_t* file, Dssdisc_t* disc)
{
	State_t*	state;

	if (!(state = vmnewof(file->dss->vm, 0, State_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	file->data = state;
	if (file->flags & DSS_FILE_WRITE)
		state->data = (char*)(state + 1);
	return 0;
}
Esempio n. 6
0
static int
ftfopen(Dssfile_t* file, Dssdisc_t* disc)
{
	State_t*	state;

	if (!sfreserve(file->io, file->ident & ((1<<20)-1), 0))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "heaxder read error");
		return -1;
	}
	if (!(state = vmnewof(file->dss->vm, 0, State_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	file->data = state;
	state->swap = (file->ident >> 28) & ((1<<4)-1);
	state->version = (file->ident >> 20) & ((1<<8)-1);
	switch (state->version)
	{
	case 1:
		state->size = sizeof(Rec_1_t);
		break;
	case 5:
		state->size = sizeof(Rec_5_t);
		break;
	case 6:
		state->size = sizeof(Rec_6_t);
		break;
	case 7:
		state->size = sizeof(Rec_7_t);
		break;
	}
	state->chunk = (1024 * 1024 + state->size - 1) / state->size;
	if (file->flags & DSS_FILE_WRITE)
		state->data = (char*)(state + 1);
	state->record.version = state->version;
	return 0;
}
Esempio n. 7
0
int
pssttyadd(register Pss_t* pss, const char* name, Pss_dev_t dev)
{
	register Tty_t*	tty;

	if (!dtmatch(pss->ttybyname, name))
	{
		if (!(tty = vmnewof(pss->vm, 0, Tty_t, 1, strlen(name))))
		{
			if (pss->disc->errorf)
				(*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space");
			return -1;
		}
		strcpy(tty->name, name);
		tty->dev = dev;
		dtinsert(pss->ttybyname, tty);
		if (!dtmatch(pss->ttybydev, &dev))
			dtinsert(pss->ttybydev, tty);
	}
	return 0;
}
Esempio n. 8
0
Pss_t*
pssopen(Pssdisc_t* disc)
{
	register Pss_t*	pss;
	Vmalloc_t*	vm;

	if (!disc)
		return 0;
	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)) || !(pss = vmnewof(vm, 0, Pss_t, 1, 0)))
		goto bad;
	pss->id = lib;
	pss->disc = disc;
	pss->vm = vm;
	pss->ttybynamedisc.key = offsetof(Tty_t, name);
	pss->ttybynamedisc.size = 0;
	pss->ttybynamedisc.link = offsetof(Tty_t, byname);
	pss->ttybydevdisc.key = offsetof(Tty_t, dev);
	pss->ttybydevdisc.size = sizeof(Pss_dev_t);
	pss->ttybydevdisc.link = offsetof(Tty_t, bydev);
	if (!(pss->ttybyname = dtnew(pss->vm, &pss->ttybynamedisc, Dtset)) ||
	    !(pss->ttybydev = dtnew(pss->vm, &pss->ttybydevdisc, Dtset)))
		goto bad;
	pss->meth = (_pss_ps && ((disc->flags & PSS_PS) || getenv("_PSS_ps"))) ? _pss_ps : _pss_method;
	while (pss->meth->initf && (*pss->meth->initf)(pss) <= 0)
		if (pss->meth == _pss_ps || !(pss->meth = _pss_ps))
		{
			vmclose(vm);
			return 0;
		}
	return pss;
 bad:
	if (disc->errorf)
		(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
	if (vm)
		vmclose(vm);
	return 0;
}
Esempio n. 9
0
Dssfile_t*
dssfopen(Dss_t* dss, const char* path, Sfio_t* io, Dssflags_t flags, Dssformat_t* format)
{
	Dssfile_t*	file;
	Vmalloc_t*	vm;
	char*		s;
	size_t		n;
	int		i;
	struct stat	st;
	Sfdisc_t	top;
	char		buf[PATH_MAX];

	if (flags & DSS_FILE_WRITE)
	{
		if (io)
		{
			memset(&top, 0, sizeof(top));
			if (sfdisc(io, &top))
			{
				n = top.disc == &dss->state->compress_preferred;
				sfdisc(io, SF_POPDISC);
				if (n)
				{
					sfdisc(io, SF_POPDISC);
					sfdczip(io, path, dss->meth->compress ? dss->meth->compress : "gzip", dss->disc->errorf);
				}
			}
		}
		if (dss->flags & DSS_APPEND)
			flags |= DSS_FILE_APPEND;
	}
	if (!path || !*path || streq(path, "-"))
	{
		if (flags & DSS_FILE_WRITE)
		{
			if (io)
				path = "output-stream";
			else
			{
				path = "/dev/stdout";
				io = sfstdout;
			}
		}
		else if (io)
			path = "input-stream";
		else
		{
			path = "/dev/stdin";
			io = sfstdin;
		}
		flags |= DSS_FILE_KEEP;
	}
	else if (io)
		flags |= DSS_FILE_KEEP;
	else if (flags & DSS_FILE_WRITE)
	{
		if (!(io = sfopen(NiL, path, (flags & DSS_FILE_APPEND) ? "a" : "w")))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot open", path);
			return 0;
		}
	}
	else if (!(io = dssfind(path, "", DSS_VERBOSE, buf, sizeof(buf), dss->disc)))
		return 0;
	else
		path = (const char*)buf;
	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		return 0;
	}
	if (!(file = vmnewof(vm, 0, Dssfile_t, 1, strlen(path) + 1)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		if (!(flags & DSS_FILE_KEEP))
			sfclose(io);
		vmclose(vm);
		return 0;
	}
	strcpy(file->path = (char*)(file + 1), path);
	file->dss = dss;
	file->vm = vm;
	file->io = io;
	file->flags = flags;
	if (flags & DSS_FILE_WRITE)
	{
		if (!(file->format = format) && !(file->format = dss->format))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, 2, "output method format must be specified");
			if (!(flags & DSS_FILE_KEEP))
				sfclose(io);
			return 0;
		}
		file->readf = noreadf;
		file->writef = file->format->writef;
	}
	else
	{
		if (sfsize(file->io) || !fstat(sffileno(file->io), &st) && (S_ISFIFO(st.st_mode)
#ifdef S_ISSOCK
			|| S_ISSOCK(st.st_mode)
#endif
			))
		{
			if (sfdczip(file->io, file->path, NiL, dss->disc->errorf) < 0)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: inflate error", file->path);
				dssfclose(file);
				return 0;
			}
			s = sfreserve(file->io, SF_UNBOUND, SF_LOCKR);
			n = sfvalue(file->io);
			if (!s)
			{
				if (n && dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot peek", file->path);
				dssfclose(file);
				return 0;
			}
			for (file->format = (Dssformat_t*)dtfirst(dss->meth->formats); file->format && !(i = (*file->format->identf)(file, s, n, dss->disc)); file->format = (Dssformat_t*)dtnext(dss->meth->formats, file->format));
			sfread(file->io, s, 0);
			if (!file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: unknown %s format", file->path, dss->meth->name);
				dssfclose(file);
				return 0;
			}
			if (i < 0)
				return 0;
			if (format && format != file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s file format %s incompatible with %s", file->path, dss->meth->name, file->format->name, format->name);
				dssfclose(file);
				return 0;
			}
			if ((dss->flags & DSS_VERBOSE) && dss->disc->errorf)
				(*dss->disc->errorf)(dss, dss->disc, 1, "%s: %s method %s format", file->path, dss->meth->name, file->format->name);
			file->readf = file->format->readf;
		}
		else
		{
			file->format = format ? format : dss->format ? dss->format : (Dssformat_t*)dtfirst(dss->meth->formats);
			file->readf = nullreadf;
		}
		file->writef = nowritef;
		if (!dss->format)
			dss->format = file->format;
	}
	if (!file->format)
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s method did not set file format", file->path, dss->meth->name);
		dssfclose(file);
		return 0;
	}
	file->record.file = file;
	if ((*file->format->openf)(file, dss->disc))
	{
		dssfclose(file);
		return 0;
	}
	return file;
}
Esempio n. 10
0
Pssent_t*
pssread(register Pss_t* pss, Pss_id_t pid)
{
	register unsigned long	fields = pss->meth->fields;
	register unsigned long	flags = pss->disc->flags;
	register Pssent_t*	pe;
	Pssmatch_t*		mp;
	Pssdata_t*		dp;
	unsigned long		x;
	int			i;

	for (;;)
	{
		if ((*pss->meth->readf)(pss, pid) <= 0)
			return 0;
		if (!pss->ent && !(pss->ent = vmnewof(pss->vm, 0, Pssent_t, 1, 0)))
		{
			if (pss->disc->errorf)
				(*pss->disc->errorf)(pss, pss->disc, ERROR_SYSTEM|2, "out of space");
			return 0;
		}
		pe = pss->ent;
		if ((i = (*pss->meth->partf)(pss, pe)) < 0)
			return 0;
		if (!i)
		{
			memset(pe, 0, sizeof(*pe));
			pe->pid = pss->pid;
			goto next;
		}
		if (pid)
			pe->pss = PSS_EXPLICIT;
		else if (flags & PSS_ALL)
			pe->pss = PSS_MATCHED;
		else
		{
			if (flags & (PSS_ATTACHED|PSS_DETACHED|PSS_LEADER|PSS_NOLEADER|PSS_TTY|PSS_UID))
			{
				if ((flags & PSS_TTY) && pe->tty != TTYMAP(pss, pss->disc->tty))
					goto next;
				if ((flags & PSS_UID) && pe->uid != pss->disc->uid)
					goto next;
				switch (flags & (PSS_ATTACHED|PSS_DETACHED))
				{
				case PSS_ATTACHED:
					if (pe->tty == PSS_NODEV)
						goto next;
					break;
				case PSS_DETACHED:
					if (pe->tty != PSS_NODEV)
						goto next;
					break;
				}
				switch (flags & (PSS_LEADER|PSS_NOLEADER))
				{
				case PSS_LEADER:
					if ((fields & PSS_sid) && pe->pid != pe->sid)
						goto next;
					if ((fields & PSS_tgrp) && pe->pid != pe->tgrp)
						goto next;
					break;
				case PSS_NOLEADER:
					if ((fields & PSS_sid) && pe->pid == pe->sid)
						goto next;
					if ((fields & PSS_tgrp) && pe->pid == pe->tgrp)
						goto next;
					break;
				}
				pe->pss = PSS_MATCHED;
			}
			if (mp = pss->disc->match)
			{
				do
				{
					switch (mp->field)
					{
					case PSS_gid:
						x = pe->gid;
						break;
					case PSS_pgrp:
						x = pe->pgrp;
						break;
					case PSS_sid:
						x = pe->sid;
						break;
					case PSS_tgrp:
						x = pe->tgrp;
						break;
					case PSS_tty:
						x = pe->tty;
						if (pss->meth->ttymapf)
							for (dp = mp->data; dp; dp = dp->next)
								dp->data = TTYMAP(pss, dp->data);
						break;
					case PSS_uid:
						x = pe->uid;
						break;
					default:
						if (pss->disc->errorf)
							(*pss->disc->errorf)(pss, pss->disc, 2, "%08lx selection not implemented", mp->field);
						return 0;
					}
					for (dp = mp->data; dp; dp = dp->next)
						if (dp->data == x)
							break;
				} while (!dp && (mp = mp->next));
				if (!mp)
					goto next;
				pe->pss = PSS_MATCHED;
			}
		}
		break;
	next:
		if (flags & PSS_UNMATCHED)
		{
			pe->pss = 0;
			break;
		}
		if (pid)
			return 0;
	}
	if (pss->meth->fullf && (*pss->meth->fullf)(pss, pe) <= 0)
		return 0;
	if (pe->pid <= 1 && pe->ppid > 1)
	{
		pe->ppid = 0;
		if (pe->pid == 0)
			pe->args = pe->command = "sched";
	}
	return pe;
}
Esempio n. 11
0
int
pzheadread(register Pz_t* pz)
{
	register int		i;
	register int		n;
	register unsigned char*	s;
	size_t			m;
	Pzpart_t*		pp;

	if (pz->flags & PZ_HEAD)
		return 0;

	/*
	 * check the header magic
	 */

	if (s = (unsigned char*)sfreserve(pz->io, 4, 1))
	{
		i = s[0];
		n = s[1];
	}
	else
		i = n = 0;
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzheadread: f=%08x i=%02x n=%02x partition=%s%s", pz->path, pz->flags, i, n, pz->disc->partition, s ? "" : " (nil)");
	if (i != PZ_MAGIC_1 || n != PZ_MAGIC_2 || s[2] == 0 || s[3] >= 10)
	{
		sfread(pz->io, s, 0);
		if (pz->flags & PZ_SPLIT)
			return 0;
		if (pz->flags & PZ_DISC)
		{
			pz->flags &= ~PZ_POP;
			return -1;
		}
		if (!(pz->flags & (PZ_READ|PZ_WRITE|PZ_STAT)) && (m = pz->prefix.count))
		{
			if (pz->prefix.terminator >= 0)
			{
				while (m-- > 0)
				{
					if (!sfgetr(pz->io, pz->prefix.terminator, 0))
					{
						if (pz->disc->errorf)
							(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
						return -1;
					}
				}
			}
			else if (!sfreserve(pz->io, m, 0))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
				return -1;
			}
		}
		if (!(n = pz->row))
		{
			if ((pz->flags & PZ_ACCEPT) || !sfsize(pz->io))
				n = 1;
			else if ((n = pzfixed(pz, pz->io, NiL, 0)) <= 0 && pz->disc->partition)
			{
				pz->flags |= PZ_ROWONLY;
				if (!pzpartition(pz, pz->disc->partition))
					n = pz->row;
				pz->flags &= ~PZ_ROWONLY;
			}
		}
		if (n <= 0)
		{
			if (!(pz->flags & PZ_DELAY) && (pz->disc->partition || !(pz->flags & PZ_FORCE)))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: unknown input format", pz->path);
				return -1;
			}
			pz->flags |= PZ_UNKNOWN;
			n = 1;
		}
		if (!(pp = vmnewof(pz->vm, 0, Pzpart_t, 1, 0)))
			return -1;
		pz->major = PZ_MAJOR;
		pz->minor = PZ_MINOR;
		pp->name = "";
		pp->row = n;
		return pzpartinit(pz, pp, NiL);
	}
	sfread(pz->io, s, 2);
	pz->flags &= ~PZ_FORCE;
	pz->major = sfgetc(pz->io);
	pz->minor = sfgetc(pz->io);
	switch (pz->major)
	{
	case 1:
		if (pz->minor <= 2)
			goto noway;
		break;
	case 2:
		pz->win = sfgetu(pz->io);
		break;
	default:
		goto noway;
	}
	pz->flags |= PZ_HEAD;
	return pzpartread(pz);
 noway:
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data %d.%d not supported by implementation %d.%d", pz->path, pz->major, pz->minor, PZ_MAJOR, PZ_MINOR);
	return -1;
}
Esempio n. 12
0
int
dssprintf(Dss_t* dss, Cx_t* cx, Sfio_t* sp, const char* format, Dssrecord_t* record)
{
	register char*	s;
	register char*	t;
	register char*	d;
	register char*	v;
	register int	n;
	register int	q;
	register Arg_t*	ap;
	int		l;
	int		x;
	char*		f;
	char*		o;
	char*		w;
	Format_t*	fp;
	Fmt_t		fmt;

	if (!cx)
		cx = dss->cx;
	for (fp = dss->print; fp && fp->oformat != (char*)format; fp = fp->next);
	if (!fp)
	{
		if (f = s = (char*)format)
		{
			char*	details['z' - 'a' + 1];

			memset(details, 0, sizeof(details));
			d = 0;
			l = 0;
			n = 0;
			q = 0;
			w = 0;
			for (;;)
			{
				switch (*s++)
				{
				case 0:
					if (q)
					{
						if (dss->disc->errorf)
							(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: format character omitted", f);
						return -1;
					}
					break;
				case '%':
					if (*s != '%')
					{
						q = 1;
						n++;
						f = s - 1;
					}
					continue;
				case '(':
					if (q == 1)
					{
						q++;
						for (;;)
						{
							switch (*s++)
							{
							case 0:
								s--;
								break;
							case '(':
								q++;
								continue;
							case ')':
								if (--q == 1)
									break;
								continue;
							case ':':
								if (*s == ':')
									s++;
								else if (!d)
									d = s;
								continue;
							default:
								continue;
							}
							break;
						}
						if (d)
						{
							l += s - d + 1;
							d = 0;
						}
					}
					continue;
				case 'c':
				case 'd':
				case 'e':
				case 'f':
				case 'g':
				case 'o':
				case 's':
				case 'u':
				case 'x':
					if (q == 1)
						q = 0;
					continue;
				default:
					continue;
				}
				break;
			}
			if (!(fp = vmnewof(dss->vm, 0, Format_t, 1, (n - 1) * sizeof(Arg_t) + strlen(format) + 2 * n + l + 2)))
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
				return -1;
			}
			fp->oformat = (char*)format;
			fp->next = dss->print;
			dss->print = fp;
			ap = &fp->arg[0];
			s = t = fp->nformat = (char*)(&fp->arg[n]);
			strcpy(t, format);
			f = t + strlen(format) + 2 * n + 1;
			q = 0;
			d = 0;
			l = 0;
			for (;;)
			{
				switch (*t++ = *s++)
				{
				case 0:
					*(t - 1) = '\n';
					*t = 0;
					break;
				case '%':
					if (*s == '%')
						*t++ = *s++;
					else
						q = 1;
					continue;
				case '(':
					if (q == 1)
					{
						q++;
						t--;
						x = 0;
						v = s;
						for (;;)
						{
							switch (*s++)
							{
							case 0:
								if (dss->disc->errorf)
									(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %(...) imbalance", fp->oformat);
								return -1;
							case '(':
								if (!d)
									x = 1;
								q++;
								continue;
							case ')':
								if (--q == 1)
									break;
								continue;
							case ':':
								if (*s == ':')
									s++;
								else if (!d && q == 2)
									d = s;
								continue;
							case ',':
								if (!d)
									x = 1;
								continue;
							default:
								if (!d && cx->table->opcode[*(unsigned char*)(s - 1)])
									x = 1;
								continue;
							}
							break;
						}
						if (d)
							*(d - 1) = 0;
						*(s - 1) = 0;
						if (*v)
						{
							if (x)
							{
								void*	pop;
	
								if (!(pop = cxpush(cx, NiL, NiL, v, (d ? d : s) - v, 0)))
									return -1;
								ap->expr = cxcomp(cx);
								cxpop(cx, pop);
								if (!ap->expr)
									return -1;
							}
							else if (cx->referencef)
							{
								Cxoperand_t	a;
								Cxoperand_t	b;
								Cxoperand_t	r;
	
								a.type = cx->state->type_string;
								a.value.string.size = s - v - 1;
								a.value.string.data = v;
								b.type = a.type;
								if ((*cx->referencef)(cx, NiL, &r, &b, &a, NiL, cx->disc))
									return -1;
								ap->variable = r.value.variable;
							}
							else if (!(ap->variable = cxvariable(cx, v, NiL, cx->disc)))
								return -1;
						}
						else if (d)
						{
							w = d;
							d = 0;
						}
					}
					continue;
				case 'c':
					if (q == 1)
					{
						ap->type = DSS_FORMAT_char;
						ap->cast = cx->state->type_number;
						goto set;
					}
					continue;
				case 'd':
				case 'o':
				case 'u':
				case 'x':
					if (q == 1)
					{
						if (l > 1 || ap->variable && (ap->variable->format.width == 8 || ap->variable->type->format.width == 8))
						{
							n = *(t - 1);
							*(t - 1) = 'l';
							*t++ = 'l';
							*t++ = n;
							ap->type = DSS_FORMAT_long;
						}
						else
							ap->type = DSS_FORMAT_int;
						ap->cast = cx->state->type_number;
						goto set;
					}
					continue;
				case 'e':
				case 'f':
				case 'g':
					if (q == 1)
					{
						ap->type = DSS_FORMAT_float;
						ap->cast = cx->state->type_number;
						goto set;
					}
					continue;
				case 'h':
					if (q == 1)
						t--;
					continue;
				case 'l':
					if (q == 1)
					{
						t--;
						l++;
					}
					continue;
				case 's':
					if (q == 1)
					{
						ap->type = DSS_FORMAT_string;
						ap->cast = cx->state->type_string;
					set:
						if (w)
						{
							details[*(s-1) - 'a'] = w;
							w = 0;
							fp->nformat = t = s;
							continue;
						}
						if (!ap->variable && !ap->expr)
						{
							if (dss->disc->errorf)
							{
								*t = 0;
								(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: (variable) omitted in format", fp->nformat);
							}
							return -1;
						}
						l = 0;
						q = 0;
						if (d || (d = details[*(s-1) - 'a']) || (d = cx->state->type_string->format.details))
						{
							ap->fmt = FMT_ALWAYS|FMT_ESCAPED;
							while (*d)
							{
								o = 0;
								v = d;
								while (*d)
									if (*d++ == ':')
									{
										*(o = d - 1) = 0;
										break;
									}
								if (strneq(v, "edit=", 5))
								{
									if (o)
										*o = ':';
									if (ap->edit = cxedit(cx, v + 5, dss->disc))
									{
										d = v + 5 + ap->edit->re.re_npat;
										if (d == o)
											d++;
									}
								}
								else if (strneq(v, "endquote=", 8))
								{
									ap->qe = v += 8;
									while (*f++ = *v++);
								}
								else if (streq(v, "expand"))
								{
									ap->fmt |= FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE;
									continue;
								}
								else if (strneq(v, "expand=", 7))
								{
									v += 7;
									while (*v)
									{
										if (*v == '|' || *v == ',')
										{
											v++;
											continue;
										}
										if (strneq(v, "all", 3))
										{
											ap->fmt |= FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE;
											break;
										}
										else if (strneq(v, "char", 4))
										{
											v += 4;
											ap->fmt |= FMT_EXP_CHAR;
										}
										else if (strneq(v, "line", 4))
										{
											v += 4;
											ap->fmt |= FMT_EXP_LINE;
										}
										else if (strneq(v, "nocr", 4))
										{
											v += 4;
											ap->fmt |= FMT_EXP_NOCR;
										}
										else if (strneq(v, "nonl", 4))
										{
											v += 4;
											ap->fmt |= FMT_EXP_NONL;
										}
										else if (strneq(v, "wide", 4))
										{
											v += 4;
											ap->fmt |= FMT_EXP_WIDE;
										}
										else
											while (*v && *v != '|' && *v != ',')
												v++;
									}
									continue;
								}
								else if (streq(v, "escape"))
									ap->fmt &= ~FMT_ESCAPED;
								else if (strneq(v, "opt", 3))
									ap->fmt &= ~FMT_ALWAYS;
								else if (streq(v, "quote") || strneq(v, "quote=", 6))
								{
									if (v[5])
									{
										ap->qb = v += 6;
										while (*f++ = *v++);
									}
									else
										ap->qb = "\"";
									if (!ap->qe)
										ap->qe = ap->qb;
								}
								else if (streq(v, "shell") || strneq(v, "shell=", 6))
								{
									ap->fmt |= FMT_SHELL;
									if (v[5])
									{
										ap->qb = v += 6;
										while (*f++ = *v++);
									}
									else
										ap->qb = "$'";
									if (!ap->qe)
										ap->qe = "'";
								}
								else if (streq(v, "wide"))
									ap->fmt |= FMT_WIDE;
								else
								{
									if (*d)
										*(d - 1) = ':';
									d = v;
									break;
								}
								ap->flags |= DSS_FORMAT_quote;
							}
							ap->details = f;
							while (*f++ = *d++);
							d = 0;
						}
						if (ap->variable && !ap->edit && cxisstring(ap->variable->type) && ap->variable->format.map && ap->variable->format.map->part && ap->variable->format.map->part->edit)
							ap->edit = ap->variable->format.map->part->edit;
						ap++;
					}
					continue;
				case 'L':
					if (q == 1)
					{
						t--;
						l += 2;
					}
					continue;
				default:
					continue;
				}
				break;
			}
		}
		else
		{
			Cxvariable_t*	vp;

			n = q = 0;
			if (dss->meth->cx->fields)
			{
				for (vp = (Cxvariable_t*)dtfirst(dss->meth->cx->fields); vp; vp = (Cxvariable_t*)dtnext(dss->meth->cx->fields, vp), n++)
					if (!(vp->header.flags & CX_DEPRECATED) && q < (l = strlen(vp->name)))
						q = l;
			}
			else if (dss->meth->data)
			{
				for (vp = (Cxvariable_t*)dss->meth->data; vp->name; vp++, n++)
					if (!(vp->header.flags & CX_DEPRECATED) && q < (l = strlen(vp->name)))
						q = l;
			}
			q += 2;
			if (!(fp = vmnewof(dss->vm, 0, Format_t, 1, n * sizeof(Arg_t) + n * (q + 3) + 2)))
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
				return -1;
			}
			fp->oformat = 0;
			fp->next = dss->print;
			dss->print = fp;
			ap = &fp->arg[0];
			s = fp->nformat = (char*)(&fp->arg[n]);
			*s++ = '\n';
			vp = dss->meth->cx->fields ? (Cxvariable_t*)dtfirst(dss->meth->cx->fields) : dss->meth->data ? (Cxvariable_t*)dss->meth->data : 0;
			if (vp)
				for (;;)
				{
					if (dss->meth->cx->fields)
					{
						if (!vp)
							break;
					}
					else if (!vp->name)
						break;
					if (!(vp->header.flags & CX_DEPRECATED))
					{
						s += sfsprintf(s, q + 4, "%-*s%%s\n", q, vp->name);
						ap->variable = vp;
						ap->type = DSS_FORMAT_string;
						ap->cast = cx->state->type_string;
						if (cxisstring(vp->type) && vp->format.map && vp->format.map->part && vp->format.map->part->edit)
							ap->edit = vp->format.map->part->edit;
						ap++;
					}
					if (dss->meth->cx->fields)
						vp = (Cxvariable_t*)dtnext(dss->meth->cx->fields, vp);
					else
						vp++;
				}
			*s = 0;
		}
		if (!sp)
			return 0;
	}
	memset(&fmt, 0, sizeof(fmt));
	fmt.fmt.version = SFIO_VERSION;
	fmt.fmt.form = fp->nformat;
	fmt.fmt.extf = getfmt;
	fmt.cx = cx;
	fmt.data = record;
	fmt.ap = &fp->arg[0];
	n = sfprintf(sp, "%!", &fmt);
	return !sp ? 0 : (fmt.errors || n <= 0 && sp && sferror(sp)) ? -1 : n;
}
Esempio n. 13
0
static int
validate_sel(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
{
	register State_t*	state = (State_t*)expr->data;
	register Field_t*	field;
	register Cxconstraint_t*constraint;
	Cxoperand_t		o;
	Cxinstruction_t		x;
	Invalid_t		key;
	Invalid_t*		ip;
	size_t			n;

	for (field = state->field; field; field = field->next)
	{
		x.data.variable = field->variable;
		if ((*state->getf)(cx, &x, &o, NiL, NiL, data, disc))
			return -1;
		if (field->variable->format.map)
		{
			if (cxisstring(field->variable->type))
			{
				if (cxstr2num(cx, &field->variable->format, o.value.string.data, o.value.string.size, NiL))
				{
					if (state->verbose && disc->errorf)
						(*disc->errorf)(NiL, disc, 1, "%s%s: %-.*s: unknown map name", cxlocation(cx, data), field->variable->name, o.value.string.size, o.value.string.data);
					goto invalid;
				}
			}
			else if (cxisnumber(field->variable->type))
			{
				if (cxnum2str(cx, &field->variable->format, (Cxinteger_t)o.value.number, NiL))
				{
					if (state->verbose && disc->errorf)
						(*disc->errorf)(NiL, disc, 1, "%s%s: %I*d: unknown map value", cxlocation(cx, data), field->variable->name, sizeof(Cxinteger_t), (Cxinteger_t)o.value.number);
					goto invalid;
				}
			}
		}
		if (constraint = field->variable->format.constraint)
		{
			if (constraint->constraintf)
				;
			if (cxisnumber(field->variable->type))
			{
				if (constraint->min && o.value.number < constraint->min->number)
				{
					if (state->verbose && disc->errorf)
						(*disc->errorf)(NiL, disc, 1, "%s%s: %1.15Lg violates min constraint %1.15Lg", cxlocation(cx, data), field->variable->name, o.value.number, constraint->min->number);
					goto invalid;
				}
				if (constraint->max && o.value.number > constraint->max->number)
				{
					if (state->verbose && disc->errorf)
						(*disc->errorf)(NiL, disc, 1, "%s%s: %1.15Lg violates max constraint %1.15Lg", cxlocation(cx, data), field->variable->name, o.value.number, constraint->max->number);
					goto invalid;
				}
			}
			if (constraint->expression)
				;
			if (constraint->pattern)
				;
		}
		continue;
	invalid:
		if (state->invalid)
		{
			key.variable = field->variable;
			key.value = o.value;
			if (!(ip = (Invalid_t*)dtsearch(state->invalid, &key)))
			{
				n = cxsize(field->variable->type, &o.value);
				if (!(ip = vmnewof(state->vm, 0, Invalid_t, 1, n)))
				{
					if (disc->errorf)
						(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
					return -1;
				}
				*ip = key;
				ip->value = o.value;
				if (n)
				{
					ip->value.buffer.data = (void*)(ip + 1);
					memcpy(ip->value.buffer.data, o.value.buffer.data, n);
				}
				dtinsert(state->invalid, ip);
				ip->count = 0;
			}
			ip->count++;
		}
		if (state->setf && constraint && constraint->def)
		{
			o.type = field->variable->type;
			o.value = *constraint->def;
			if ((*state->setf)(cx, &x, &o, &o, NiL, data, disc))
				return -1;
			field->repaired++;
		}
		else if (state->discard)
		{
			field->discarded++;
			return 0;
		}
		else
			field->invalid++;
	}
	return 1;
}
Esempio n. 14
0
static int
validate_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
{
	char**			argv = (char**)data;
	int			errors = error_info.errors;
	char*			s;
	State_t*		state;
	Cxvariable_t*		variable;
	register Field_t*	field;
	Field_t*		lastfield;
	Cxconstraint_t*		constraint;
	int			all;
	int			list;
	Vmalloc_t*		vm;

	if (!(vm = vmopen(Vmdcheap, Vmlast, 0)) || !(state = vmnewof(vm, 0, State_t, 1, 0)))
	{
		if (vm)
			vmclose(vm);
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	state->vm = vm;
	list = 0;
	sfprintf(cx->buf, "%s%s", strchr(dss_lib_validate.description, '['), validate_usage);
	s = sfstruse(cx->buf);
	for (;;)
	{
		switch (optget(argv, s))
		{
		case 'd':
			state->discard = 1;
			continue;
		case 'l':
			list = 1;
			continue;
		case 'r':
			if (!(state->setf = cxcallout(cx, CX_SET, cx->state->type_void, cx->state->type_void, cx->disc)))
			{
				if (cx->disc->errorf)
					(*cx->disc->errorf)(NiL, cx->disc, 3, "reair requires CX_SET callout");
				return -1;
			}
			continue;
		case 's':
			state->summary = 1;
			continue;
		case 'v':
			state->summary = state->verbose = 1;
			continue;
		case '?':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
			else
				return -1;
			continue;
		case ':':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
			else
				return -1;
			continue;
		}
		break;
	}
	if (error_info.errors > errors)
		goto bad;
	argv += opt_info.index;
	if (all = !*argv)
		variable = 0;
	do
	{
		if (all)
		{
			if (!(variable = (Cxvariable_t*)(variable ? dtnext(cx->fields, variable) : dtfirst(cx->fields))))
				break;
		}
		else if (!(variable = cxvariable(cx, *argv, NiL, disc)))
			goto bad;
		if (variable->format.constraint || variable->format.map)
		{
			if (!(field = vmnewof(vm, 0, Field_t, 1, 0)))
			{
				if (disc->errorf)
					(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
				goto bad;
			}
			field->variable = variable;
			if (state->field)
				lastfield = lastfield->next = field;
			else
				lastfield = state->field = field;
		}
	} while (all || *++argv);
	if (!state->field && disc->errorf)
		(*disc->errorf)(NiL, disc, 1, "no field has constraints or maps");
	if (list)
	{
		for (field = state->field; field; field = field->next)
		{
			sfprintf(expr->op, "%16s", field->variable->name);
			if (field->variable->format.map)
				sfprintf(expr->op, " map");
			if (constraint = field->variable->format.constraint)
			{
				if (constraint->name)
					sfprintf(expr->op, " name=%s", constraint->name);
				if (constraint->constraintf)
					sfprintf(expr->op, " external");
				if (cxisnumber(field->variable->type))
				{
					if (constraint->def)
						number(expr->op, "default", constraint->def->number, &field->variable->format);
					if (constraint->min)
						number(expr->op, "min", constraint->min->number, &field->variable->format);
					if (constraint->max)
						number(expr->op, "max", constraint->max->number, &field->variable->format);
				}
				else if (cxisstring(field->variable->type) && constraint->def)
					sfprintf(expr->op, " default=\"%-.*s\"", constraint->def->string.size, constraint->def->string.data);
				if (constraint->expression)
					sfprintf(expr->op, " expression=\"%s\"", constraint->expression);
				if (constraint->pattern)
					sfprintf(expr->op, " pattern=\"%s\"", constraint->pattern);
			}
			sfprintf(expr->op, "\n");
		}
		goto bad;
	}
	if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout");
		goto bad;
	}
	if (!state->verbose)
	{
		state->invaliddisc.comparf = invalidcmp;
		if (!(state->invalid = dtnew(vm, &state->invaliddisc, Dtoset)))
		{
			if (cx->disc->errorf)
				(*cx->disc->errorf)(NiL, cx->disc, 3, "validation requires CX_GET callout");
			goto bad;
		}
	}
	expr->data = state;
	return 0;
 bad:
	vmclose(vm);
	return -1;
}
Esempio n. 15
0
static int
merge_beg(Cx_t* cx, Cxexpr_t* expr, void* data, Cxdisc_t* disc)
{
	register State_t*	state;
	register File_t*	file;
	char**			argv = (char**)data;
	char**			files = expr->files;
	Dss_t*			dss = DSS(cx);
	int			errors = error_info.errors;
	int			i;
	int			k;
	int			n;
	int			r;
	char*			path;
	char*			u;
	char**			v;
	Cxvariable_t*		variable;
	Cxoperand_t*		operands;
	Key_t*			key;
	Key_t*			lastkey;
	Key_t*			keys;
	Vmalloc_t*		vm;

	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
	{
		if (disc->errorf)
			(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
		return -1;
	}
	r = -1;
	k = 0;
	keys = 0;
	sfprintf(cx->buf, "%s%s", strchr(dss_lib_merge.description, '['), merge_usage);
	u = sfstruse(cx->buf);
	for (;;)
	{
		switch (i = optget(argv, u))
		{
		case 'k':
		case 'r':
			if (!(variable = cxvariable(cx, opt_info.arg, NiL, disc)))
				goto bad;
			if (!(key = vmnewof(vm, 0, Key_t, 1, 0)))
			{
				if (disc->errorf)
					(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
				goto bad;
			}
			key->variable = variable;
			key->sense = (i == 'r') ? -1 : 1;
			if (keys)
				lastkey = lastkey->next = key;
			else
				lastkey = keys = key;
			k++;
			continue;
		case '?':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
			else
				return -1;
			continue;
		case ':':
			if (disc->errorf)
				(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
			else
				return -1;
			continue;
		}
		break;
	}
	if (error_info.errors > errors)
		goto bad;
	argv += opt_info.index;
	for (v = argv; *v; v++);
	n = v - argv;
	if (files)
	{
		for (v = files; *v; v++);
		n += v - files;
	}
	if (!n)
		n = 1;
	if (!(state = vmnewof(vm, 0, State_t, 1, (n - 1) * sizeof(File_t))) || !(operands = vmnewof(vm, 0, Cxoperand_t, n * k, 0)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space");
		goto bad;
	}
	state->cx = cx;
	if (!(state->getf = cxcallout(cx, CX_GET, cx->state->type_void, cx->state->type_void, cx->disc)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, 2, "CX_GET callout required");
		goto bad;
	}
	state->nfiles = n;
	state->nkeys = k;
	state->keys = keys;
	for (n = 0; n < state->nfiles; n++)
	{
		state->files[n].data = operands;
		operands += k;
	}
	state->orderdisc.comparf = ordercmp;
	if (!(state->order = dtnew(vm, &state->orderdisc, Dtoset)))
	{
		if (cx->disc->errorf)
			(*cx->disc->errorf)(NiL, cx->disc, ERROR_SYSTEM|2, "out of space");
		goto bad;
	}
	n = 0;
	if (path = *argv)
		argv++;
	else if (files)
	{
		argv = files;
		files = 0;
		if (path = *argv)
			argv++;
	}
	for (;;)
	{
		if (!(state->files[n].file = dssfopen(dss, path, NiL, DSS_FILE_READ, NiL)))
			goto drop;
		enter(dss, state, &state->files[n]);
		n++;
		if (!(path = *argv++))
		{
			if (!files)
				break;
			argv = files;
			files = 0;
			if (!(path = *argv++))
				break;
		}
	}
	expr = expr->pass;
	if (dssbeg(dss, expr))
		goto drop;
	while (file = (File_t*)dtfirst(state->order))
	{
		if (dsseval(dss, expr, file->record) < 0)
			goto drop;
		enter(dss, state, file);
	}
	if (error_info.errors == errors)
		r = 0;
 drop:
	for (n = 0; n < state->nfiles; n++)
		if (state->files[n].file)
			dssfclose(state->files[n].file);
 bad:
	vmclose(vm);
	return r;
}