about summary refs log tree commit diff
path: root/vlogger.c
blob: cd32143df61d2978231bdb8cb8b0f1a16ffacf97 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <limits.h>

static char pwd[PATH_MAX];

typedef struct {
  const char *const c_name;
  int c_val;
} CODE;

CODE prioritynames[] = {
	{ "alert", LOG_ALERT },
	{ "crit", LOG_CRIT },
	{ "debug", LOG_DEBUG },
	{ "emerg", LOG_EMERG },
	{ "err", LOG_ERR },
	{ "error", LOG_ERR },
	{ "info", LOG_INFO },
	{ "notice", LOG_NOTICE },
	{ "panic", LOG_EMERG },
	{ "warn", LOG_WARNING },
	{ "warning", LOG_WARNING },
	{ 0, -1 }
};

CODE facilitynames[] = {
	{ "auth", LOG_AUTH },
	{ "authpriv", LOG_AUTHPRIV },
	{ "cron", LOG_CRON },
	{ "daemon", LOG_DAEMON },
	{ "ftp", LOG_FTP },
	{ "kern", LOG_KERN },
	{ "lpr", LOG_LPR },
	{ "mail", LOG_MAIL },
	{ "news", LOG_NEWS },
	{ "security", LOG_AUTH },
	{ "syslog", LOG_SYSLOG },
	{ "user", LOG_USER },
	{ "uucp", LOG_UUCP },
	{ "local0", LOG_LOCAL0 },
	{ "local1", LOG_LOCAL1 },
	{ "local2", LOG_LOCAL2 },
	{ "local3", LOG_LOCAL3 },
	{ "local4", LOG_LOCAL4 },
	{ "local5", LOG_LOCAL5 },
	{ "local6", LOG_LOCAL6 },
	{ "local7", LOG_LOCAL7 },
	{ 0, -1 }
};

static void
strpriority(char *s, int *facility, int *level)
{
	char *p;
	CODE *cp;

	if ((p = strchr(s, '.'))) {
		*p++ = 0;
		for (cp = prioritynames; cp->c_name; cp++) {
			if (strcmp(cp->c_name, p) == 0)
				*level = cp->c_val;
		}
	}
	if (*s)
		for (cp = facilitynames; cp->c_name; cp++) {
			if (strcmp(cp->c_name, s) == 0)
				*facility = cp->c_val;
		}
}

int
main(int argc, char *argv[])
{
	char c, *p, *argv0;
	char *tag = NULL;
	int facility = LOG_DAEMON;
	int level = LOG_INFO;

	argv0 = *argv;

	if (strcmp(argv0, "./run") == 0) {
		p = getcwd(pwd, sizeof (pwd));
		if (p != NULL && *pwd == '/') {
			if (*(p = pwd+(strlen(pwd)-1)) == '/')
				*p = '\0';
			if ((p = strrchr(pwd, '/')) && strncmp(p+1, "log", 3) == 0 &&
			    (*p = '\0', (p = strrchr(pwd, '/'))) && (*(p+1) != '\0')) {
				tag = strdup(p+1);
			}
		}
	}

	while ((c = getopt(argc, argv, "p:t:")) != -1)
		switch (c) {
		case 'p': strpriority(optarg, &facility, &level); break;
		case 't': tag = optarg; break;
		default:
usage:
			fprintf(stderr, "usage: vlogger [-p priority] [-t tag]\n");
			exit(1);
		}

	if (tag == NULL)
		goto usage;

	if (access("/etc/vlogger", X_OK) != -1) {
		execl("/etc/vlogger", argv0, tag, (char *)0);
		fprintf(stderr, "vlogger: exec: %s\n", strerror(errno));
		exit(1);
	}

	openlog(tag, 0, facility);

	char *line;
	size_t linelen = 0;
	ssize_t rd;
	while ((rd = getline(&line, &linelen, stdin)) != -1) {
		if (line[rd-1] == '\n')
			line[rd-1] = '\0';
		syslog(level|facility, "%s", line);
	}

	return 1;
}