47
47
#include <sys/types.h>
48
48
#include <sys/socket.h>
49
49
#include <sys/un.h>
50
#include <arpa/inet.h>
52
58
#define SYSLOG_NAMES
53
59
#include <syslog.h>
55
61
int decode __P((char *, CODE *));
56
62
int pencode __P((char *));
57
void usage __P((void));
59
64
static int optd = 0;
65
static int udpport = 514;
62
68
myopenlog(const char *sock) {
64
70
static struct sockaddr_un s_addr; /* AF_UNIX address of local logger */
66
if (strlen(sock) >= sizeof(s_addr.sun_path)) {
67
printf (_("logger: openlog: pathname too long\n"));
72
if (strlen(sock) >= sizeof(s_addr.sun_path))
73
errx(EXIT_FAILURE, _("openlog %s: pathname too long"), sock);
71
75
s_addr.sun_family = AF_UNIX;
72
76
(void)strcpy(s_addr.sun_path, sock);
74
if ((fd = socket(AF_UNIX, optd ? SOCK_DGRAM : SOCK_STREAM, 0)) == -1) {
75
printf (_("socket: %s.\n"), strerror(errno));
79
if (connect(fd, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1) {
80
printf (_("connect: %s.\n"), strerror(errno));
78
if ((fd = socket(AF_UNIX, optd ? SOCK_DGRAM : SOCK_STREAM, 0)) == -1)
79
err(EXIT_FAILURE, _("socket %s"), sock);
81
if (connect(fd, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1)
82
err(EXIT_FAILURE, _("connect %s"), sock);
88
udpopenlog(const char *servername,int port) {
90
struct sockaddr_in s_addr;
91
struct hostent *serverhost;
93
if ((serverhost = gethostbyname(servername)) == NULL )
94
errx(EXIT_FAILURE, _("unable to resolve '%s'"), servername);
96
if ((fd = socket(AF_INET, SOCK_DGRAM , 0)) == -1)
97
err(EXIT_FAILURE, _("socket"));
99
bcopy(serverhost->h_addr,&s_addr.sin_addr,serverhost->h_length);
100
s_addr.sin_family=AF_INET;
101
s_addr.sin_port=htons(port);
103
if (connect(fd, (struct sockaddr *) &s_addr, sizeof(s_addr)) == -1)
104
err(EXIT_FAILURE, _("connect"));
87
109
mysyslog(int fd, int logflags, int pri, char *tag, char *msg) {
88
110
char buf[1000], pid[30], *cp, *tp;
136
static void __attribute__ ((__noreturn__)) usage(FILE *out)
138
fputs(_("\nUsage:\n"), out);
140
_(" %s [options] [message]\n"), program_invocation_short_name);
142
fputs(_("\nOptions:\n"), out);
143
fputs(_(" -d, --udp use UDP (TCP is default)\n"
144
" -i, --id log the process ID too\n"
145
" -f, --file <file> log the contents of this file\n"
146
" -h, --help display this help text and exit\n"), out);
147
fputs(_(" -n, --server <name> write to this remote syslog server\n"
148
" -P, --port <number> use this UDP port\n"
149
" -p, --priority <prio> mark given message with this priority\n"
150
" -s, --stderr output message to standard error as well\n"), out);
151
fputs(_(" -t, --tag <tag> mark every line with this tag\n"
152
" -u, --socket <socket> write to this Unix socket\n"
153
" -V, --version output version information and exit\n\n"), out);
155
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
115
159
* logger -- read and log utility
122
166
int ch, logflags, pri;
123
167
char *tag, buf[1024];
124
168
char *usock = NULL;
169
char *udpserver = NULL;
125
170
int LogSock = -1;
173
static const struct option longopts[] = {
174
{ "id", no_argument, 0, 'i' },
175
{ "stderr", no_argument, 0, 's' },
176
{ "file", required_argument, 0, 'f' },
177
{ "priority", required_argument, 0, 'p' },
178
{ "tag", required_argument, 0, 't' },
179
{ "socket", required_argument, 0, 'u' },
180
{ "udp", no_argument, 0, 'd' },
181
{ "server", required_argument, 0, 'n' },
182
{ "port", required_argument, 0, 'P' },
183
{ "version", no_argument, 0, 'V' },
184
{ "help", no_argument, 0, 'h' },
127
188
setlocale(LC_ALL, "");
128
189
bindtextdomain(PACKAGE, LOCALEDIR);
132
193
pri = LOG_NOTICE;
134
while ((ch = getopt(argc, argv, "f:ip:st:u:d")) != -1)
195
while ((ch = getopt_long(argc, argv, "f:ip:st:u:dn:P:Vh",
196
longopts, NULL)) != -1) {
135
197
switch((char)ch) {
136
198
case 'f': /* file to log */
137
if (freopen(optarg, "r", stdin) == NULL) {
139
(void)fprintf(stderr, _("logger: %s: %s.\n"),
140
optarg, strerror(errsv));
199
if (freopen(optarg, "r", stdin) == NULL)
200
err(EXIT_FAILURE, _("file %s"),
144
203
case 'i': /* log process id also */
145
204
logflags |= LOG_PID;
160
219
optd = 1; /* use datagrams */
221
case 'n': /* udp socket */
222
optd = 1; /* use datagrams because udp */
225
case 'P': /* change udp port */
226
tmpport = strtol_or_err(optarg,
227
_("failed to parse port number"));
228
if (tmpport < 0 || 65535 < tmpport)
229
errx(EXIT_FAILURE, _("port `%ld' out of range"),
231
udpport = (int) tmpport;
234
printf(_("%s from %s\n"), program_invocation_short_name,
169
247
/* setup for logging */
248
if (!usock && !udpserver)
171
249
openlog(tag ? tag : getlogin(), logflags, 0);
251
LogSock = udpopenlog(udpserver,udpport);
173
253
LogSock = myopenlog(usock);
182
262
for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) {
183
263
len = strlen(*argv);
184
264
if (p + len > endp && p > buf) {
265
if (!usock && !udpserver)
186
266
syslog(pri, "%s", buf);
188
268
mysyslog(LogSock, logflags, pri, tag, buf);
191
271
if (len > sizeof(buf) - 1) {
272
if (!usock && !udpserver)
193
273
syslog(pri, "%s", *argv++);
195
275
mysyslog(LogSock, logflags, pri, tag, *argv++);
207
287
mysyslog(LogSock, logflags, pri, tag, buf);
210
290
while (fgets(buf, sizeof(buf), stdin) != NULL) {
211
291
/* glibc is buggy and adds an additional newline,
212
292
so we have to remove it here until glibc is fixed */