Welcome to little lamb

Code » slicd » commit 74af741

Add slicd-dump

author Olivier Brunel
2016-05-16 17:46:05 UTC
committer Olivier Brunel
2016-05-17 16:43:20 UTC
parent 3e4be8d0bd75dff4c4efae4c8d5684cd547b8a74

Add slicd-dump

doc/slicd-dump.pod +42 -0
doc/slicd-parser.pod +1 -1
doc/slicd-sched.pod +1 -1
package/modes +1 -0
package/targets.mak +2 -0
src/slicd/deps-exe/slicd-dump +2 -0
src/slicd/slicd-dump.c +188 -0

diff --git a/doc/slicd-dump.pod b/doc/slicd-dump.pod
new file mode 100644
index 0000000..51c8474
--- /dev/null
+++ b/doc/slicd-dump.pod
@@ -0,0 +1,42 @@
+=head1 NAME
+
+slicd-dump - Print content of "compiled" crontabs
+
+=head1 SYNOPSIS
+
+B<slicd-dump> I<FILE>
+
+=head1 OPTIONS
+
+=over
+
+=item B<-h, --help>
+
+Show help screen and exit.
+
+=item B<-V, --version>
+
+Show version information and exit.
+
+=back
+
+=head1 DESCRIPTION
+
+B<slicd-dump>(1) is a small helper that will print the content of a "compiled"
+crontabs file, generated via B<slicd-parser>(1), in human readable format.
+
+It will list all jobs in the file, with for each of them the job line (in the
+form "USERNAME:COMMAND LINE" as would be printed by B<slicd-sched>(1)), and for
+each fields (Minutes, Hours, etc) the matching values.
+
+Values will be printed in a format compatible for the B<slicd-parser>(1): an
+asterisk (*) when all allowed values match, or a list of values/ranges as
+needed. For fields "Days" and "Days of the month" it will use names.
+
+It will be noted when special DST mode was enabled, and/or when "days combo" is
+activated (using both "Days" and "Days of the week" to mean e.g. 2nd Wednesday
+of the month; see B<slicd-parser>(1) for more).
+
+=head1 SEE ALSO
+
+B<slicd-parser>(1), B<slicd-sched>(1)
diff --git a/doc/slicd-parser.pod b/doc/slicd-parser.pod
index 9511ae0..dc9e4ac 100644
--- a/doc/slicd-parser.pod
+++ b/doc/slicd-parser.pod
@@ -176,4 +176,4 @@ B<--users-dirs>)
 
 =head1 SEE ALSO
 
-B<slicd-sched>(1), B<slicd-exec>(1)
+B<slicd-dump>(1), B<slicd-sched>(1), B<slicd-exec>(1)
diff --git a/doc/slicd-sched.pod b/doc/slicd-sched.pod
index 95cf2f7..e3b19e9 100644
--- a/doc/slicd-sched.pod
+++ b/doc/slicd-sched.pod
@@ -140,4 +140,4 @@ The following return values are possible:
 
 =head1 SEE ALSO
 
-B<slicd-parser>(1), B<slicd-exec>(1)
+B<slicd-dump>(1), B<slicd-parser>(1), B<slicd-exec>(1)
diff --git a/package/modes b/package/modes
index a8c1247..cf17125 100644
--- a/package/modes
+++ b/package/modes
@@ -1,3 +1,4 @@
+slicd-dump              0755
 slicd-parser            0755
 slicd-sched             0755
 slicd-exec              0755
diff --git a/package/targets.mak b/package/targets.mak
index 0ab7a5d..cae3edd 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,4 +1,5 @@
 BIN_TARGETS := \
+slicd-dump \
 slicd-parser \
 slicd-sched \
 slicd-exec \
@@ -7,6 +8,7 @@ miniexec
 
 DOC_TARGETS := \
 slicd.1 \
+slicd-dump.1 \
 slicd-parser.1 \
 slicd-sched.1 \
 slicd-exec.1 \
diff --git a/src/slicd/deps-exe/slicd-dump b/src/slicd/deps-exe/slicd-dump
new file mode 100644
index 0000000..96c7a85
--- /dev/null
+++ b/src/slicd/deps-exe/slicd-dump
@@ -0,0 +1,2 @@
+${LIBSLICD}
+-lskarnet
diff --git a/src/slicd/slicd-dump.c b/src/slicd/slicd-dump.c
new file mode 100644
index 0000000..adf0be6
--- /dev/null
+++ b/src/slicd/slicd-dump.c
@@ -0,0 +1,188 @@
+/*
+ * slicd - Copyright (C) 2016 Olivier Brunel
+ *
+ * slicd-dump.c
+ * Copyright (C) 2016 Olivier Brunel <jjk@jjacky.com>
+ *
+ * This file is part of slicd.
+ *
+ * slicd is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * slicd is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * slicd. If not, see http://www.gnu.org/licenses/
+ */
+
+#include "slicd/config.h"
+
+#include <getopt.h>
+#include <slicd/slicd.h>
+#include <slicd/job.h>
+#include <slicd/fields.h>
+#include <slicd/die.h>
+#include <skalibs/buffer.h>
+#include <skalibs/uint.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/strerr2.h>
+
+static slicd_t slicd = { 0, };
+
+#define job_str(job)        (slicd.str.s + job->offset)
+
+static void
+dieusage (int rc)
+{
+    slicd_die_usage (rc, "FILE",
+            " -h, --help                    Show this help screen and exit\n"
+            " -V, --version                 Show version information and exit\n"
+            );
+}
+
+static void
+put_uint (unsigned int u, slicd_field_t field)
+{
+    if (field == SLICD_MONTHS || field == SLICD_DAYS_OF_WEEK)
+    {
+        const char *names[] = {
+            "JanFebMarAprMayJunJulAugSepOctNovDec",
+            "SunMonTueWedThuFriSat"
+        };
+
+        buffer_put (buffer_1small, names[field - 3] + (u - _slicd_fields[field].adjust) * 3, 3);
+    }
+    else
+    {
+        char buf[UINT_FMT];
+
+        buf[uint_fmt (buf, u)] = '\0';
+        buffer_puts (buffer_1small, buf);
+    }
+}
+
+int
+main (int argc, char * const argv[])
+{
+    PROG = "slicd-dump";
+    unsigned int i, nb;
+    int r;
+
+    for (;;)
+    {
+        struct option longopts[] = {
+            { "help",               no_argument,        NULL,   'h' },
+            { "version",            no_argument,        NULL,   'V' },
+            { NULL, 0, 0, 0 }
+        };
+        int c;
+
+        c = getopt_long (argc, argv, "hV", longopts, NULL);
+        if (c == -1)
+            break;
+        switch (c)
+        {
+            case 'h':
+                dieusage (0);
+
+            case 'V':
+                slicd_die_version ();
+
+            default:
+                dieusage (1);
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    if (argc != 1)
+        dieusage (1);
+
+    r = slicd_load (&slicd, argv[0]);
+    if (r < 0)
+        strerr_diefu3sys (2, "load compiled crontabs from '", argv[0], "'");
+
+    nb = genalloc_len (slicd_job_t, &slicd.jobs);
+    for (i = 0; i < nb; ++i)
+    {
+        slicd_job_t *job = &genalloc_s (slicd_job_t, &slicd.jobs)[i];
+        const char *name[] = { "Minutes", "Hours", "Days", "Months", "Days of the week" };
+        int field;
+
+        buffer_puts (buffer_1small, "Job ");
+        put_uint (i + 1, 0);
+        buffer_puts (buffer_1small, "/");
+        put_uint (nb, 0);
+        buffer_puts (buffer_1small, ": ");
+        buffer_puts (buffer_1small, job_str (job));
+        buffer_puts (buffer_1small, "\n");
+
+        for (field = 0; field < 5; ++field)
+        {
+            int first = _slicd_fields[field].adjust;
+            int max = _slicd_fields[field].adjust + _slicd_fields[field].max;
+
+            buffer_puts (buffer_1small, name[field]);
+            buffer_puts (buffer_1small, ": ");
+            r = slicd_job_first (job, field, first, max, 0);
+            if (r > max)
+                buffer_puts (buffer_1small, "*");
+            else
+            {
+                int last = -1;
+                int interval = 0;
+
+                for (;;)
+                {
+                    r = slicd_job_first (job, field, first, max, 1);
+                    if (r > max)
+                    {
+out:
+                        if (interval)
+                        {
+                            buffer_puts (buffer_1small, "-");
+                            put_uint (last, field);
+                        }
+                        break;
+                    }
+
+                    if (last < 0)
+                        put_uint (r, field);
+                    else if (r > last + 1)
+                    {
+                        if (interval)
+                        {
+                            buffer_puts (buffer_1small, "-");
+                            put_uint (last, field);
+                        }
+                        interval = 0;
+                        buffer_puts (buffer_1small, ",");
+                        put_uint (r, field);
+                    }
+                    else
+                        interval = 1;
+
+                    last = r;
+                    first = r + 1;
+                    if (first > max)
+                        goto out;
+                }
+            }
+            buffer_puts (buffer_1small, "\n");
+        }
+
+        if (slicd_job_has_dst_special (job))
+            buffer_puts (buffer_1small, "Special DST mode enabled.\n");
+        if (slicd_job_has_days_combo (job))
+            buffer_puts (buffer_1small, "Note: Days Combo activated.\n");
+        buffer_putsflush (buffer_1small, "\n");
+    }
+
+    slicd_free (&slicd);
+    return 0;
+}