File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / Attic / clog.c
Revision 1.1.2.10: download - view: text, annotated - select for diffs - revision graph
Wed Jun 8 09:36:11 2011 UTC (13 years, 2 months ago) by misho
Branches: tools1_0
fix type between bsd-s

#include "global.h"
#include "clog.h"


int Verbose;
extern char compiled[], compiledby[], compilehost[];


static void
Usage()
{

	printf(	"cLOG is tool for managment syslogd operation with circular logs\n"
		"=== %s === %s@%s ===\n\n"
		"  Syntax: clog [options] <file.log>\n\n"
		"\t-v\t\tVerbose, more -vv more verbosity\n"
		"\t-i\t\tInit file.log, create and prepare for use\n"
		"\t-s <size>\tUse with init for set needed file.log size\n"
		"\t-m <perm>\tUse permissions with init for set file.log\n"
		"\t-f\t\tRead and follow log file.log\n"
		"\n", compiled, compiledby, compilehost);
}

static int
initlog(const char *csLog, size_t size, int mode)
{
	int f, ret = -1, fill = size;
	struct clogFooter cf = { 0 };
	char buffer[BUFLEN] = { 0 };

	memcpy(&cf.cf_magic, MAGIC, sizeof cf.cf_magic);
	cf.cf_max = size - sizeof cf;

	f = open(csLog, O_WRONLY | O_CREAT | O_TRUNC, mode);
	if (f == -1) {
		printf("Error:: in open log %s #%d - %s\n", csLog, errno, strerror(errno));
		return -1;
	} else
		VERB(1) printf("Verbose:: Create log %s\n", csLog);
	while (fill > BUFLEN)
		if (write(f, buffer, BUFLEN) == -1) {
			printf("Error:: in fill log %s #%d - %s\n", csLog, errno, strerror(errno));
			goto end;
		} else
			fill -= BUFLEN;
	if (fill > BUFLEN) {
		printf("Error:: in fill log %s uninspected result!!!\n", csLog);
		goto end;
	} else if (fill && write(f, buffer, fill) == -1) {
		printf("Error:: in last fill log %s #%d - %s\n", csLog, errno, strerror(errno));
		goto end;
	}
	// return to write cfooter
	if (lseek(f, -(off_t)(sizeof cf), SEEK_END) == -1) {
		printf("Error:: can`t set position for write footer #%d - %s\n", errno, strerror(errno));
		goto end;
	}
	if (write(f, &cf, sizeof cf) == -1) {
		printf("Error:: in footer log %s #%d - %s\n", csLog, errno, strerror(errno));
		goto end;
	}

	ret = 0;
	VERB(1) printf("Verbose:: Init done.\n");
end:
	close(f);
	return ret;
}

static int
readlog(const char *csLog, char m)
{
	int f, cx;
	size_t end;
	struct clogFooter *cf;
	char *buffer = NULL;
	uint32_t next, start = 0;
	struct iovec iov[2];
	struct pollfd pfd = { 0 };

	f = open(csLog, O_RDONLY);
	if (f == -1) {
		printf("Error:: in open read %s #%d - %s\n", csLog, errno, strerror(errno));
		return -1;
	} else
		VERB(1) printf("Verbose:: Opened log %s\n", csLog);
	end = lseek(f, 0, SEEK_END);
	if (end == -1) {
		printf("Error:: in get size %s #%d - %s\n", csLog, errno, strerror(errno));
		close(f);
		return -1;
	} else
		lseek(f, 0, SEEK_SET);
	VERB(2) printf("Verbose(2):: Get file size %lu\n", (u_long) end);
	buffer = mmap(NULL, end, PROT_READ, MAP_SHARED, f, 0);
	if (!buffer) {
		printf("Error:: in map %s #%d - %s\n", csLog, errno, strerror(errno));
		close(f);
		return -1;
	} else {
		close(f);

		cf = (struct clogFooter*) (buffer + end - sizeof(struct clogFooter));
		VERB(3) printf("Verbose(3):: Map file to address %p and footer %p\n", buffer, cf);
	}

	if (cf->cf_wrap == 1)
		start = cf->cf_next + 1;
	VERB(3) printf("Verbose(3):: wrapped log? %d\n", cf->cf_wrap);
	do {
		cx = 0;
		while (cf->cf_lock == 1)
			sched_yield();
		next = cf->cf_next;

		if (start > next) {
			iov[cx].iov_base = buffer + start;
			iov[cx++].iov_len = cf->cf_max - start;
			start = 0;
		}
		iov[cx].iov_base = buffer + start;
		iov[cx++].iov_len = next - start;
		start = next;
		writev(1, iov, cx);
		if (!(m & 2))
			break;
		if (poll(&pfd, 1, 50) == -1) {
			printf("Error:: in poll %s #%d - %s\n", csLog, errno, strerror(errno));
			munmap(buffer, end);
			return -1;
		}
	} while (42);

	munmap(buffer, end);
	VERB(1) printf("Verbose:: Read done.\n");
	return 0;
}


int
main(int argc, char **argv)
{
	char ch, m = 0, szLog[MAXPATHLEN];
	size_t siz = 0;
	int mode = 0644;

	while ((ch = getopt(argc, argv, "hm:vfis:")) != -1)
		switch (ch) {
			case 'm':
				mode = strtol(optarg, NULL, 0);
				break;
			case 'v':
				Verbose++;
				break;
			case 'i':
				m |= 1;
				break;
			case 'f':
				m |= 2;
				break;
			case 's':
				siz = strtol(optarg, NULL, 0);
				if (siz < 1) {
					printf("Error:: size is invalid %lu!\n", (u_long) siz);
					Usage();
					return 1;
				}
				break;
			case 'h':
			default:
				Usage();
				return 1;
		}
	argc -= optind;
	argv += optind;
	if (m & 1 && !siz) {
		printf("Error:: not specified size when use with init log!\n");
		Usage();
		return 1;
	}
	if (m == 3) {
		printf("Error:: can`t in same time init and force!\n");
		Usage();
		return 1;
	}
	if (!argc) {
		printf("Error:: not specified log file!\n");
		Usage();
		return 1;
	} else
		strlcpy(szLog, *argv, MAXPATHLEN);

	if (m & 1 && initlog(szLog, siz, mode) == -1)
		return 2;
	if (readlog(szLog, m) == -1)
		return 3;

	return 0;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>