#include #include #include #include #include #include #include static char pwd[PATH_MAX + 1]; 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 = "vlogger"; int facility = LOG_DAEMON; int level = LOG_INFO; size_t pwdlen = 0; argv0 = *argv; if (!strcmp(argv0, "./run")) { p = getcwd(pwd, sizeof(pwd)); if (p == NULL) { /* FIXME: roll our own getcwd that does dynamic allocation? */ fprintf(stderr, "vlogger: getcwd: %s\n", strerror(errno)); exit(1); } if (pwd[0] != '/') { fprintf(stderr, "Current working directory is not reachable or not absolute.\n"); exit(1); } pwdlen = strlen(pwd); if (pwd[pwdlen - 1] == '/') pwd[pwdlen - 1] = '\0'; if ((p = strrchr(pwd, '/')) && !strncmp(p+1, "log", 3) && (*p = 0, (p = strrchr(pwd, '/'))) && (*(p + 1) != 0)) { if (!(tag = strdup(p+1))) { fprintf(stderr, "vlogger: strdup: %s\n", strerror(errno)); exit(1); } } } while ((c = getopt(argc, argv, "p:t:")) != -1) switch (c) { case 'p': strpriority(optarg, &facility, &level); break; case 't': tag = optarg; break; default: fprintf(stderr, "usage: vlogger [-p priority] [-t tag]\n"); exit(1); } 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; }