static void logger_stdin(struct logger_ctl *ctl) { char *msg; int default_priority = ctl->pri; char buf[1024]; while (fgets(buf, sizeof(buf), stdin) != NULL) { int len = strlen(buf); /* some glibc versions are buggy, they add an additional * newline which is removed here. */ if (0 < len && buf[len - 1] == '\n') buf[len - 1] = '\0'; msg = buf; ctl->pri = default_priority; if (ctl->prio_prefix && msg[0] == '<') msg = get_prio_prefix(msg, &ctl->pri); ctl->syslogfp(ctl, msg); } }
/* * logger -- read and log utility * * Reads from an input and arranges to write the result on the system * log. */ int main(int argc, char **argv) { int ch, logflags, pri, prio_prefix; char *tag, buf[1024]; char *usock = NULL; char *server = NULL; char *port = NULL; int LogSock = -1, socket_type = ALL_TYPES; #ifdef HAVE_LIBSYSTEMD FILE *jfd = NULL; #endif static const struct option longopts[] = { { "id", no_argument, 0, 'i' }, { "stderr", no_argument, 0, 's' }, { "file", required_argument, 0, 'f' }, { "priority", required_argument, 0, 'p' }, { "tag", required_argument, 0, 't' }, { "socket", required_argument, 0, 'u' }, { "udp", no_argument, 0, 'd' }, { "tcp", no_argument, 0, 'T' }, { "server", required_argument, 0, 'n' }, { "port", required_argument, 0, 'P' }, { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX }, #ifdef HAVE_LIBSYSTEMD { "journald", optional_argument, 0, OPT_JOURNALD }, #endif { NULL, 0, 0, 0 } }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); tag = NULL; pri = LOG_NOTICE; logflags = 0; prio_prefix = 0; while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh", longopts, NULL)) != -1) { switch (ch) { case 'f': /* file to log */ if (freopen(optarg, "r", stdin) == NULL) err(EXIT_FAILURE, _("file %s"), optarg); break; case 'i': /* log process id also */ logflags |= LOG_PID; break; case 'p': /* priority */ pri = pencode(optarg); break; case 's': /* log to standard error */ logflags |= LOG_PERROR; break; case 't': /* tag */ tag = optarg; break; case 'u': /* unix socket */ usock = optarg; break; case 'd': socket_type = TYPE_UDP; break; case 'T': socket_type = TYPE_TCP; break; case 'n': server = optarg; break; case 'P': port = optarg; break; case 'V': printf(UTIL_LINUX_VERSION); exit(EXIT_SUCCESS); case 'h': usage(stdout); case OPT_PRIO_PREFIX: prio_prefix = 1; break; #ifdef HAVE_LIBSYSTEMD case OPT_JOURNALD: if (optarg) { jfd = fopen(optarg, "r"); if (!jfd) err(EXIT_FAILURE, _("cannot open %s"), optarg); } else jfd = stdin; break; #endif case '?': default: usage(stderr); } } argc -= optind; argv += optind; /* setup for logging */ #ifdef HAVE_LIBSYSTEMD if (jfd) { int ret = journald_entry(jfd); if (stdin != jfd) fclose(jfd); return ret ? EXIT_FAILURE : EXIT_SUCCESS; } #endif if (server) LogSock = inet_socket(server, port, socket_type); else if (usock) LogSock = unix_socket(usock, socket_type); else openlog(tag ? tag : getlogin(), logflags, 0); /* log input line if appropriate */ if (argc > 0) { register char *p, *endp; size_t len; for (p = buf, endp = buf + sizeof(buf) - 2; *argv;) { len = strlen(*argv); if (p + len > endp && p > buf) { if (!usock && !server) syslog(pri, "%s", buf); else mysyslog(LogSock, logflags, pri, tag, buf); p = buf; } if (len > sizeof(buf) - 1) { if (!usock && !server) syslog(pri, "%s", *argv++); else mysyslog(LogSock, logflags, pri, tag, *argv++); } else { if (p != buf) *p++ = ' '; memmove(p, *argv++, len); *(p += len) = '\0'; } } if (p != buf) { if (!usock && !server) syslog(pri, "%s", buf); else mysyslog(LogSock, logflags, pri, tag, buf); } } else { char *msg; int default_priority = pri; while (fgets(buf, sizeof(buf), stdin) != NULL) { /* glibc is buggy and adds an additional newline, so we have to remove it here until glibc is fixed */ int len = strlen(buf); if (len > 0 && buf[len - 1] == '\n') buf[len - 1] = '\0'; msg = buf; pri = default_priority; if (prio_prefix && msg[0] == '<') msg = get_prio_prefix(msg, &pri); if (!usock && !server) syslog(pri, "%s", msg); else mysyslog(LogSock, logflags, pri, tag, msg); } } if (!usock && !server) closelog(); else close(LogSock); return EXIT_SUCCESS; }