author | Olivier Brunel
<jjk@jjacky.com> 2015-12-28 18:14:16 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2016-01-12 14:33:47 UTC |
parent | 8bf0e70a1fe35dfa94eef4510ef1b8c90f0bb255 |
src/include/slicd/err.h | +2 | -0 |
src/include/slicd/job.h | +3 | -0 |
src/libslicd/deps-lib/slicd | +1 | -0 |
src/libslicd/errmsg.c | +3 | -1 |
src/libslicd/slicd_add_job_from_cronline.c | +27 | -70 |
src/libslicd/slicd_job_ensure_valid.c | +89 | -0 |
src/libslicd/slicd_load.c | +21 | -0 |
diff --git a/src/include/slicd/err.h b/src/include/slicd/err.h index 6674675..733d11a 100644 --- a/src/include/slicd/err.h +++ b/src/include/slicd/err.h @@ -36,6 +36,8 @@ enum SLICD_ERR_DAYS_COMBO, SLICD_ERR_IMPOSSIBLE_DATE, SLICD_ERR_NO_USERNAME, + SLICD_ERR_NO_MATCH, + SLICD_ERR_INVALID_JOB, _SLICD_NB_ERR }; diff --git a/src/include/slicd/job.h b/src/include/slicd/job.h index 7cf41b5..08e5a27 100644 --- a/src/include/slicd/job.h +++ b/src/include/slicd/job.h @@ -67,4 +67,7 @@ extern int slicd_job_first (slicd_job_t *job, int to, int what); + +extern int slicd_job_ensure_valid (slicd_job_t *job); + #endif /* SLICD_JOB_H */ diff --git a/src/libslicd/deps-lib/slicd b/src/libslicd/deps-lib/slicd index fb9cf1f..7410daa 100644 --- a/src/libslicd/deps-lib/slicd +++ b/src/libslicd/deps-lib/slicd @@ -7,6 +7,7 @@ slicd_die_usage.o slicd_die_version.o slicd_free.o slicd_job.o +slicd_job_ensure_valid.o slicd_job_next_run.o slicd_load.o slicd_save.o diff --git a/src/libslicd/errmsg.c b/src/libslicd/errmsg.c index e61e728..2e2000b 100644 --- a/src/libslicd/errmsg.c +++ b/src/libslicd/errmsg.c @@ -33,5 +33,7 @@ const char const *slicd_errmsg[_SLICD_NB_ERR] = { "Syntax error", "Out of range days alongside days of the week", "Impossible date matching (e.g. Feb 31)", - "No username specified" + "No username specified", + "No possible match (field without any selection)", + "Invalid job data" }; diff --git a/src/libslicd/slicd_add_job_from_cronline.c b/src/libslicd/slicd_add_job_from_cronline.c index c82890d..363c227 100644 --- a/src/libslicd/slicd_add_job_from_cronline.c +++ b/src/libslicd/slicd_add_job_from_cronline.c @@ -169,6 +169,7 @@ slicd_add_job_from_cronline (slicd_t *slicd, { slicd_job_t j = { 0, }; const char *s = cronline; + int len; int r; int i; @@ -186,81 +187,37 @@ slicd_add_job_from_cronline (slicd_t *slicd, return r; } - /* special case: days combo */ - if (slicd_job_first (&j, SLICD_DAYS_OF_WEEK, 0, 6, 0) <= 6) - { - /* there is a restriction on DOW, now let's check how the first 6 days - * are set: - * - all set = same as '*', no restriction on DAYS - * - none set = invalid - * - a mix = DAYS_COMBO - */ - - if (slicd_job_first (&j, SLICD_DAYS, 1, 6, 0) == 7) - slicd_job_set (&j, SLICD_DAYS, 1, 31); - else if (slicd_job_first (&j, SLICD_DAYS, 1, 6, 1) == 7) - return -SLICD_ERR_DAYS_COMBO; - else - slicd_job_set_days_combo (&j, 1); - } + r = slicd_job_ensure_valid (&j); + if (r < 0) + return r; - /* ensure date validity/coherence */ - if (slicd_job_first (&j, SLICD_DAYS, 1, 29, 1) == 30) + if (username) + i = strlen (username); + else { - /* none of the first 29 days are set, so we need to do some checking: - * if day 30 is set, that there's another month than Feb, - * else (i.e. day 31 is set) that there's at least one matching month - */ - if (slicd_job_has (&j, SLICD_DAYS, 30)) - { - if (!(slicd_job_has (&j, SLICD_MONTHS, 1) - || slicd_job_first (&j, SLICD_MONTHS, 3, 12, 1) <= 12)) - return -SLICD_ERR_IMPOSSIBLE_DATE; - } - else - { - if (!(slicd_job_has (&j, SLICD_MONTHS, 1) - || slicd_job_has (&j, SLICD_MONTHS, 3) - || slicd_job_has (&j, SLICD_MONTHS, 5) - || slicd_job_has (&j, SLICD_MONTHS, 7) - || slicd_job_has (&j, SLICD_MONTHS, 8) - || slicd_job_has (&j, SLICD_MONTHS, 10) - || slicd_job_has (&j, SLICD_MONTHS, 12))) - return -SLICD_ERR_IMPOSSIBLE_DATE; - } + username = s; + for (i = 0; *s != '\0' && !is_blank (*s); ++s, ++i) + ; + skip_blanks (s); } + if (i == 0) + return -SLICD_ERR_NO_USERNAME; + if (*s == '\0') + return -SLICD_ERR_SYNTAX; - { - int len; - - if (username) - i = strlen (username); - else - { - username = s; - for (i = 0; *s != '\0' && !is_blank (*s); ++s, ++i) - ; - skip_blanks (s); - } - if (i == 0) - return -SLICD_ERR_NO_USERNAME; - if (*s == '\0') - return -SLICD_ERR_SYNTAX; - - for (len = strlen (s); is_blank (s[len - 1]); --len) - ; + for (len = strlen (s); is_blank (s[len - 1]); --len) + ; - if (!stralloc_readyplus (&slicd->str, i + 1 + len + 1) - || !genalloc_readyplus (slicd_job_t, &slicd->jobs, 1)) - return -SLICD_ERR_MEMORY; + if (!stralloc_readyplus (&slicd->str, i + 1 + len + 1) + || !genalloc_readyplus (slicd_job_t, &slicd->jobs, 1)) + return -SLICD_ERR_MEMORY; - j.offset = slicd->str.len; - stralloc_catb (&slicd->str, username, i); - stralloc_catb (&slicd->str, ":", 1); - stralloc_catb (&slicd->str, s, len); - stralloc_0 (&slicd->str); - genalloc_catb (slicd_job_t, &slicd->jobs, &j, 1); + j.offset = slicd->str.len; + stralloc_catb (&slicd->str, username, i); + stralloc_catb (&slicd->str, ":", 1); + stralloc_catb (&slicd->str, s, len); + stralloc_0 (&slicd->str); + genalloc_append (slicd_job_t, &slicd->jobs, &j); - return 1; - } + return 1; } diff --git a/src/libslicd/slicd_job_ensure_valid.c b/src/libslicd/slicd_job_ensure_valid.c new file mode 100644 index 0000000..2eda4b3 --- /dev/null +++ b/src/libslicd/slicd_job_ensure_valid.c @@ -0,0 +1,89 @@ +/* + * slicd - Copyright (C) 2015 Olivier Brunel + * + * slicd_job_ensure_valid.c + * Copyright (C) 2015 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/job.h> +#include <slicd/fields.h> +#include <slicd/err.h> + + +int +slicd_job_ensure_valid (slicd_job_t *job) +{ + int i; + + for (i = 0; i < 5; ++i) + if (slicd_job_first (job, i, _slicd_fields[i].adjust, + _slicd_fields[i].max + _slicd_fields[i].adjust, 1) + > _slicd_fields[i].max + _slicd_fields[i].adjust) + return -SLICD_ERR_NO_MATCH; + + /* special case: days combo */ + if (slicd_job_first (job, SLICD_DAYS_OF_WEEK, 0, 6, 0) <= 6) + { + /* there is a restriction on DOW, now let's check how the first 6 days + * are set: + * - all set = same as '*', no restriction on DAYS + * - none set = invalid + * - a mix = DAYS_COMBO + */ + + if (slicd_job_first (job, SLICD_DAYS, 1, 6, 0) == 7) + { + slicd_job_set (job, SLICD_DAYS, 1, 31); + slicd_job_set_days_combo (job, 0); + } + else if (slicd_job_first (job, SLICD_DAYS, 1, 6, 1) == 7) + return -SLICD_ERR_DAYS_COMBO; + else + slicd_job_set_days_combo (job, 1); + } + else + slicd_job_set_days_combo (job, 0); + + /* ensure date validity/coherence */ + if (slicd_job_first (job, SLICD_DAYS, 1, 29, 1) == 30) + { + /* none of the first 29 days are set, so we need to do some checking: + * if day 30 is set, that there's a month other than Feb, + * else (i.e. day 31 is set) that there's at least one matching month + */ + if (slicd_job_has (job, SLICD_DAYS, 30)) + { + if (!(slicd_job_has (job, SLICD_MONTHS, 1) + || slicd_job_first (job, SLICD_MONTHS, 3, 12, 1) <= 12)) + return -SLICD_ERR_IMPOSSIBLE_DATE; + } + else + { + if (!(slicd_job_has (job, SLICD_MONTHS, 1) + || slicd_job_has (job, SLICD_MONTHS, 3) + || slicd_job_has (job, SLICD_MONTHS, 5) + || slicd_job_has (job, SLICD_MONTHS, 7) + || slicd_job_has (job, SLICD_MONTHS, 8) + || slicd_job_has (job, SLICD_MONTHS, 10) + || slicd_job_has (job, SLICD_MONTHS, 12))) + return -SLICD_ERR_IMPOSSIBLE_DATE; + } + } + + return 0; +} diff --git a/src/libslicd/slicd_load.c b/src/libslicd/slicd_load.c index 9ce9d17..32ad9bd 100644 --- a/src/libslicd/slicd_load.c +++ b/src/libslicd/slicd_load.c @@ -25,6 +25,7 @@ #include <skalibs/uint32.h> #include <skalibs/djbunix.h> #include <slicd/slicd.h> +#include <slicd/job.h> #include <slicd/err.h> int @@ -101,6 +102,26 @@ slicd_load (slicd_t *slicd, const char *file) slicd->jobs.len += r; } + /* ensure loaded data are valid */ + { + int i; + + for (i = 0; i < genalloc_len (slicd_job_t, &slicd->jobs); ++i) + { + slicd_job_t *job = &genalloc_s (slicd_job_t, &slicd->jobs)[i]; + + if (job->offset >= slicd->str.len) + { + r = -SLICD_ERR_INVALID_JOB; + goto err; + } + + r = slicd_job_ensure_valid (job); + if (r < 0) + goto err; + } + } + err: { int e = errno;