aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-10-28 13:29:42 +0100
committerDavid Oberhollenzer <david.oberhollenzer@tele2.at>2018-10-28 14:25:50 +0100
commit200daf7dbbce90d4006d7dbf53affa48a110ed00 (patch)
tree939da07b50abf4a62de1b25c359e5345f1de50cc
parent49f52b1571216a4bae3a4df9944c978e3a1fb854 (diff)
Import syslog utility program
Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am4
-rw-r--r--protomap.c24
-rw-r--r--syslog.145
-rw-r--r--syslog.c184
-rw-r--r--syslogd.h6
6 files changed, 260 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 9635e08..387cb50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,4 @@ config.h
*~
klogd
usyslogd
+syslog
diff --git a/Makefile.am b/Makefile.am
index ccfe661..f4719a3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,9 @@ AM_CFLAGS = $(WARN_CFLAGS)
usyslogd_SOURCES = syslogd.c syslogd.h proto.c logfile.c mksock.c protomap.c
klogd_SOURCES = klogd.c
+syslog_SOURCES = syslog.c protomap.c
-bin_PROGRAMS =
+dist_man1_MANS = syslog.1
+bin_PROGRAMS = syslog
sbin_PROGRAMS = usyslogd klogd
EXTRA_DIST = LICENSE
diff --git a/protomap.c b/protomap.c
index 1ace2bb..60e2c6a 100644
--- a/protomap.c
+++ b/protomap.c
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: ISC */
#include "syslogd.h"
+#include <string.h>
+
typedef struct {
const char *name;
int id;
@@ -54,12 +56,30 @@ static const char *enum_to_name(const enum_map_t *map, int id)
return map->name;
}
+static int enum_by_name(const enum_map_t *map, const char *name)
+{
+ while (map->name != NULL && strcmp(map->name, name) != 0)
+ ++map;
+
+ return map->name == NULL ? -1 : map->id;
+}
+
const char *level_id_to_string(int level)
{
return enum_to_name(levels, level);
}
-const char *facility_id_to_string(int level)
+const char *facility_id_to_string(int id)
+{
+ return enum_to_name(facilities, id);
+}
+
+int level_id_from_string(const char *level)
+{
+ return enum_by_name(levels, level);
+}
+
+int facility_id_from_string(const char *fac)
{
- return enum_to_name(facilities, level);
+ return enum_by_name(facilities, fac);
}
diff --git a/syslog.1 b/syslog.1
new file mode 100644
index 0000000..2990f90
--- /dev/null
+++ b/syslog.1
@@ -0,0 +1,45 @@
+.TH syslog 1 "August 2018" "usyslog"
+.SH NAME
+syslog \- send a log message to the syslog daemon
+.SH SYNOPSIS
+.B syslog
+[options] message..
+.SH DESCRIPTION
+The syslog command concatenates all non option arguments to a single message
+that it sends to the syslog daemon.
+.SH OPTIONS
+.TP
+.BR \-h , " \-\-help"
+Display a brief help text, a list of available facilities, log levels, all the
+default setting and exit.
+.TP
+.BR \-V , " \-\-version"
+Print version information and exit.
+.TP
+.BR \-f , " \-\-facility " \fIfacility\fP
+Logging facility name or numeric identifier. Use
+.B \-\-help
+to get a list of all available facility names.
+.TP
+.BR \-l , " \-\-level " \fIlevel\fP
+A log level number from 0 to 8 with 8 being most severe, or a name from
+.I debug
+to
+.I emergency.
+Use
+.B \-\-help
+to get a list of all available log level names.
+.TP
+.BR \-i , " \-\-ident " \fIname\fP
+Program name to specify to syslog. If not set, "(shell)" is used as sensible
+default to indicate that the message came from the command line.
+.TP
+.BR \-c , " \-\-console"
+Try to write directly to the console if opening the syslog socket fails.
+.SH AVAILABILITY
+This program is part of the Pygos init system.
+.SH COPYRIGHT
+Copyright \(co 2018 David Oberhollenzer
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
diff --git a/syslog.c b/syslog.c
new file mode 100644
index 0000000..024428a
--- /dev/null
+++ b/syslog.c
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: ISC */
+#include <getopt.h>
+#include <syslog.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "syslogd.h"
+
+static int facility = 1;
+static int level = LOG_INFO;
+static int flags = LOG_NDELAY | LOG_NOWAIT;
+static const char *ident = "(shell)";
+
+static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "console", required_argument, NULL, 'c' },
+ { "facility", required_argument, NULL, 'f' },
+ { "level", required_argument, NULL, 'l' },
+ { "ident", required_argument, NULL, 'i' },
+ { NULL, 0, NULL, 0 },
+};
+
+static const char *shortopt = "hVcf:l:i:";
+
+static const char *helptext =
+"Usage: syslog [OPTION]... [STRING]...\n\n"
+"Concatenate the given STRINGs and send a log message to the syslog daemon.\n"
+"\n"
+"The following OPTIONSs can be used:\n"
+" -f, --facility <facility> Logging facilty name or numeric identifier.\n"
+" -l, --level <level> Log level name or numeric identifier.\n"
+" -i, --ident <name> Program name for log syslog message.\n"
+" Default is \"%s\".\n\n"
+" -c, --console Write to the console if opening the syslog\n"
+" socket fails.\n\n"
+" -h, --help Print this help text and exit\n"
+" -V, --version Print version information and exit\n\n";
+
+static const char *version_string =
+"syslog (usyslog) " PACKAGE_VERSION "\n"
+"Copyright (C) 2018 David Oberhollenzer\n\n"
+"This is free software: you are free to change and redistribute it.\n"
+"There is NO WARRANTY, to the extent permitted by law.\n";
+
+static void usage(int status)
+{
+ const char *str;
+ int i;
+
+ if (status != EXIT_SUCCESS) {
+ fputs("Try `syslog --help' for more information\n", stderr);
+ } else {
+ printf(helptext, ident);
+
+ fputs("The following values can be used for --level:\n",
+ stdout);
+
+ i = 0;
+ while ((str = level_id_to_string(i)) != NULL) {
+ printf(" %s (=%d)%s\n", str, i,
+ i == level ? ", set as default" : "");
+ ++i;
+ }
+
+ fputs("\nThe following values can be used for --facility:\n",
+ stdout);
+
+ i = 0;
+ while ((str = facility_id_to_string(i)) != NULL) {
+ printf(" %s (=%d)%s\n", str, i,
+ i == facility ? ", set as default" : "");
+ ++i;
+ }
+ }
+
+ exit(status);
+}
+
+static int readint(const char *str)
+{
+ int x = 0;
+
+ if (!isdigit(*str))
+ return -1;
+
+ while (isdigit(*str))
+ x = x * 10 + (*(str++)) - '0';
+
+ return (*str == '\0') ? x : -1;
+}
+
+static void process_options(int argc, char **argv)
+{
+ int c;
+
+ for (;;) {
+ c = getopt_long(argc, argv, shortopt, options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'f':
+ facility = readint(optarg);
+ if (facility >= 0)
+ break;
+ facility = facility_id_from_string(optarg);
+ if (facility < 0) {
+ fprintf(stderr, "Unknown facility name '%s'\n",
+ optarg);
+ usage(EXIT_FAILURE);
+ }
+ break;
+ case 'l':
+ level = readint(optarg);
+ if (level >= 0)
+ break;
+ level = level_id_from_string(optarg);
+ if (level < 0) {
+ fprintf(stderr, "Unknown log level '%s'\n",
+ optarg);
+ usage(EXIT_FAILURE);
+ }
+ break;
+ case 'i':
+ ident = optarg;
+ break;
+ case 'c':
+ flags |= LOG_CONS;
+ break;
+ case 'V':
+ fputs(version_string, stdout);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ size_t len = 0;
+ char *str;
+ int i;
+
+ process_options(argc, argv);
+
+ if (optind >= argc) {
+ fputs("Error: no log string provided.\n", stderr);
+ usage(EXIT_FAILURE);
+ }
+
+ for (i = optind; i < argc; ++i)
+ len += strlen(argv[i]);
+
+ len += argc - optind - 1;
+
+ str = calloc(1, len + 1);
+ if (str == NULL) {
+ fputs("syslog: out of memory\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ for (i = optind; i < argc; ++i) {
+ if (i > optind)
+ strcat(str, " ");
+ strcat(str, argv[i]);
+ }
+
+ openlog(ident, flags, facility << 3);
+ syslog(level, "%s", str);
+ closelog();
+
+ free(str);
+ return EXIT_SUCCESS;
+}
diff --git a/syslogd.h b/syslogd.h
index 740d90e..0935d1a 100644
--- a/syslogd.h
+++ b/syslogd.h
@@ -76,6 +76,10 @@ int mksock(const char *path);
const char *level_id_to_string(int level);
-const char *facility_id_to_string(int level);
+const char *facility_id_to_string(int id);
+
+int level_id_from_string(const char *level);
+
+int facility_id_from_string(const char *fac);
#endif /* LOGFILE_H */