xref: /haiku/src/bin/logger.cpp (revision 3aeed6607cd07762c0e709633c012b3a632dbad9)
1 /*
2  * Copyright 2006-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <SupportDefs.h>
8 
9 #include <pwd.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <strings.h>
14 #include <syslog.h>
15 #include <unistd.h>
16 
17 
18 #define DEFAULT_PRIORITY LOG_DEBUG
19 #define DEFAULT_FACILITY LOG_USER
20 
21 
22 extern const char *__progname;
23 static const char *sProgramName = __progname;
24 
25 
26 struct mapping {
27 	const char*	name;
28 	int			value;
29 };
30 
31 static mapping sPriorities[] = {
32 	{ "emerg",		LOG_EMERG },
33 	{ "panic",		LOG_PANIC },
34 	{ "alert",		LOG_ALERT },
35 	{ "critical",	LOG_CRIT },
36 	{ "crit",		LOG_CRIT },
37 	{ "error",		LOG_ERR },
38 	{ "err",		LOG_ERR },
39 	{ "warning", 	LOG_WARNING },
40 	{ "warn",		LOG_WARNING },
41 	{ "notice",		LOG_NOTICE },
42 	{ "info",		LOG_INFO },
43 	{ "debug",		LOG_DEBUG },
44 	{ NULL,			DEFAULT_PRIORITY },
45 };
46 
47 static mapping sFacilities[] = {
48 	{ "kernel",		LOG_KERN },
49 	{ "kern",		LOG_KERN },
50 	{ "user",		LOG_USER },
51 	{ "mail",		LOG_MAIL },
52 	{ "daemon",		LOG_DAEMON },
53 	{ "auth",		LOG_AUTH },
54 	{ "security",	LOG_AUTH },
55 	{ "syslog",		LOG_SYSLOG },
56 	{ "lpr",		LOG_LPR },
57 	{ "news",		LOG_NEWS },
58 	{ "uucp",		LOG_UUCP },
59 	{ "cron",		LOG_CRON },
60 	{ "authpriv",	LOG_AUTHPRIV },
61 	{ NULL,			DEFAULT_FACILITY },
62 };
63 
64 
65 static int
lookup_mapping(struct mapping * mappings,const char * string)66 lookup_mapping(struct mapping* mappings, const char *string)
67 {
68 	int32 i;
69 	for (i = 0; mappings[i].name != NULL; i++) {
70 		if (!strcasecmp(string, mappings[i].name))
71 			break;
72 	}
73 
74 	return mappings[i].value;
75 }
76 
77 
78 static int
get_facility(const char * option)79 get_facility(const char *option)
80 {
81 	char facility[256];
82 	strlcpy(facility, option, sizeof(facility));
83 
84 	char *end = strchr(facility, '.');
85 	if (end == NULL) {
86 		// there is no facility specified
87 		return DEFAULT_FACILITY;
88 	}
89 
90 	end[0] = '\0';
91 
92 	return lookup_mapping(sFacilities, facility);
93 }
94 
95 
96 static int
get_priority(const char * option)97 get_priority(const char *option)
98 {
99 	char *priority = strchr(option, '.');
100 	if (priority == NULL) {
101 		// there is no facility specified
102 		return DEFAULT_PRIORITY;
103 	}
104 
105 	return lookup_mapping(sPriorities, ++priority);
106 }
107 
108 
109 static void
usage(void)110 usage(void)
111 {
112 	fprintf(stderr, "usage: %s [-i] [-t <tag>] [-p <[facility.]priority>] "
113 			"<message>\n\n"
114 		"Sends a message to the system logging facility.\n"
115 		"If <message> is omitted, the message is read from stdin.\n\n"
116 		"   -i\tAdds the team ID to the log.\n"
117 		"   -t\tSpecifies the tag under which this message is posted.\n"
118 		"   -p\tSets the facility and priority this is logged under.\n"
119 		"    \t<facility> can be one of:\n"
120 		"\t\tkern, user, mail, daemon, auth, syslog, lpr, news,\n"
121 		"\t\tuucp, cron, authpriv\n"
122 		"    \t<priority> can be one of:\n"
123 		"\t\tdebug, info, notice, warning, warn, error, err,\n"
124 		"\t\tcritical, crit,alert, panic, emerg.\n", sProgramName);
125 
126 	exit(-1);
127 }
128 
129 
130 int
main(int argc,char ** argv)131 main(int argc, char **argv)
132 {
133 	struct passwd* passwd = getpwuid(geteuid());
134 	const char* tag = NULL;
135 	int facility = DEFAULT_FACILITY;
136 	int priority = DEFAULT_PRIORITY;
137 	int options = 0;
138 
139 	// read arguments
140 
141 	int option;
142 	while ((option = getopt(argc, argv, "it:p:")) != -1) {
143 		switch (option) {
144 		    case 'i':	// log team ID
145 				options |= LOG_PID;
146 				break;
147 
148 		    case 't':	// tag
149 				tag = optarg;
150 				break;
151 
152 		    case 'p':	// facility/priority
153 				facility = get_facility(optarg);
154 				priority = get_priority(optarg);
155 				break;
156 
157 		    default:
158 				usage();
159 				break;
160 		}
161 	}
162 
163 	if (tag == NULL && passwd != NULL)
164 		tag = passwd->pw_name;
165 
166 	argc -= optind;
167 	argv = &argv[optind];
168 
169 	openlog(tag, options, facility);
170 
171 	if (argc > 0) {
172 		// take message from arguments
173 
174 		char* buffer = NULL;
175 		int32 length = 0;
176 
177 		for (int32 i = 0; i < argc; i++) {
178 			int32 newLength = length + strlen(argv[i]) + 1;
179 
180 			buffer = (char *)realloc(buffer, newLength + 1);
181 			if (buffer == NULL) {
182 				fprintf(stderr, "%s: out of memory\n", sProgramName);
183 				return -1;
184 			}
185 
186 			strcpy(buffer + length, argv[i]);
187 			length = newLength;
188 
189 			buffer[length - 1] = ' ';
190 		}
191 
192 		if (length > 1 && buffer[length - 2] != '\n') {
193 			buffer[length - 1] = '\n';
194 			buffer[length] = '\0';
195 		} else
196 			buffer[length - 1] = '\0';
197 
198 		syslog(priority, "%s", buffer);
199 		free(buffer);
200 	} else {
201 		// read messages from stdin
202 
203 		char buffer[65536];
204 		while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
205 			syslog(priority, "%s", buffer);
206 		}
207 	}
208 
209 	closelog();
210 	return 0;
211 }
212 
213