Пример #1
0
int
main(int argc, char** argv)
{
	Css_t*		css;
	Cssfd_t*	fp;
	Connection_t*	con;
	char*		e;
	State_t		state;

	NoP(argc);
	error_info.id = "css";
	memset(&state, 0, sizeof(state));
	state.disc.version = CSS_VERSION;
	state.disc.flags = CSS_DAEMON|CSS_ERROR|CSS_INTERRUPT;
	state.disc.acceptf = acceptf;
	state.disc.actionf = actionf;
	state.disc.errorf = errorf;
	state.disc.exceptf = exceptf;
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 't':
			state.disc.timeout = strelapsed(opt_info.arg, &e, 1);
			if (*e)
				error(3, "%s: invalid timeout value", opt_info.arg);
			state.disc.flags |= CSS_DORMANT;
			continue;
		case '?':
			error(ERROR_USAGE|4, "%s", opt_info.arg);
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			continue;
		}
		break;
	}
	argv += opt_info.index;
	if (!argv[0] || !argv[1])
		error(ERROR_USAGE|4, "%s", optusage(NiL));
	if (!(state.tmp = sfstropen()))
		error(ERROR_SYSTEM|3, "out of space [tmp stream]");
	if (!(state.proc = procopen(argv[1], argv + 1, NiL, NiL, PROC_READ|PROC_WRITE)))
		error(ERROR_SYSTEM|3, "%s: cannot execute", argv[1]);
	if (!(css = cssopen(argv[0], &state.disc)))
		return 1;
	if (!(fp = cssfd(css, state.proc->rfd, CS_POLL_READ)))
		error(ERROR_SYSTEM|3, "%s: cannot poll output", argv[1]);
	if (!(con = newof(0, Connection_t, 1, 0)))
		error(ERROR_SYSTEM|3, "out of space");
	fp->data = con;
	con->service = 1;
	csspoll(CS_NEVER, 0);
	return 1;
}
Пример #2
0
static int
note(Css_t* css, register Connection_t* to, int log, char* s, size_t n, int force, Cssdisc_t* disc)
{
	register State_t*	state = (State_t*)disc;
	ssize_t			z;

	if ((force || to->blocked[log] < 0) && (z = data(state, to, s, n, force)) != n)
	{
		if (!force && !state->logged)
		{
			state->logged = 1;
			if (!state->logs[log].sp)
			{
				state->logs[log].name[0] = '0' + log;
				remove(state->logs[log].name);
				if (!(state->logs[log].sp = sfopen(NiL, state->logs[log].name, "r+")))
					error(ERROR_SYSTEM|3, "%s: cannot create message log", state->logs[log].name);
				message((-1, "[%d] %s: create log", __LINE__, state->logs[log].name));
			}
			message((-1, "[%d] %s: %d log", __LINE__, state->logs[log].name, to->fp->fd));
			if (sfwrite(state->logs[log].sp, s, n) != n)
				error(ERROR_SYSTEM|3, "%s: log file write error", state->logs[log].name);
			if ((state->logs[log].offset += n) >= HOG && !state->logs[!log].sp)
				state->log = !log;
		}
		if (to->blocked[log] < 0)
		{
			message((-1, "[%d] %s: block", __LINE__, state->logs[log].name));
			state->logs[log].blocked++;
		}
		to->blocked[log] = state->logs[log].offset - n + z;
		message((-1, "[%d] %s: %d offset %I*d", __LINE__, state->logs[log].name, to->fp->fd, sizeof(to->blocked[log]), to->blocked[log]));
		cssfd(css, to->fp->fd, CS_POLL_READ|CS_POLL_WRITE);
		return 0;
	}
	if (to->blocked[log] >= 0)
	{
		message((-1, "[%d] %s: %d unblock", __LINE__, state->logs[log].name, to->fp->fd));
		to->blocked[log] = -1;
		if (!--state->logs[log].blocked)
		{
			sfclose(state->logs[log].sp);
			state->logs[log].sp = 0;
			state->logs[log].offset = 0;
			remove(state->logs[log].name);
			message((-1, "[%d] %s: clear", __LINE__, state->logs[log].name));
		}
	}
	return 1;
}
Пример #3
0
static int
actionf(register Css_t* css, register Cssfd_t* fp, Cssdisc_t* disc)
{
	register State_t*	state = (State_t*)disc;
	register Connection_t*	con;
	register char*		s;
	register char*		t;
	int			n;
	int			i;

	switch (fp->status)
	{
	case CS_POLL_CLOSE:
		if (con = (Connection_t*)fp->data)
		{
			if (con->service)
				error(ERROR_SYSTEM|3, "service termination exit");
			free(con);
		}
		return 0;
	case CS_POLL_READ:
		con = (Connection_t*)fp->data;
		if ((n = csread(css->state, fp->fd, buf, sizeof(buf) - 1, CS_LINE)) <= 0)
		{
			if (con->service)
				error(ERROR_SYSTEM|3, "service termination exit");
			return -1;
		}
		buf[n] = 0;
		for (s = buf; isspace(*s); s++);
		if (con->service)
		{
			for (i = 0; isdigit(*s); i = i * 10 + *s++ - '0');
			for (; isspace(*s); s++);
			if (*s && cssfd(css, i, 0))
			{
				n -= s - buf;
				if (cswrite(css->state, i, s, n) != n)
					cssfd(css, i, CS_POLL_CLOSE);
			}
		}
		else if (*s == '!')
		{
			if ((n -= ++s - buf) > 0 && cswrite(css->state, state->proc->wfd, s, n) != n)
				return -1;
		}
		else
		{
			for (t = s; *t && !isspace(*t); t++);
			for (; isspace(*t); t++);
			if (*s == 'Q' && !*t)
			{
				if (con->id.uid == geteuid())
					error(3, "service quit exit");
			}
			else
			{
				n = sfprintf(state->tmp, "%-.*s%d %s", t - s, s, fp->fd, t);
				if (!(s = sfstruse(state->tmp)))
					return -1;
				if (cswrite(css->state, state->proc->wfd, s, n) != n)
					return -1;
			}
		}
		return 1;
	}
	return 0;
}