diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-04-22 11:14:40 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-04-22 11:14:40 +0300 |
commit | db5b8989ceefb9f1889219067be6d68651a4da2c (patch) | |
tree | a4051da0625d89a631bf3dead4dc43be7d815be5 | |
parent | 9d7ec5d8cc6ca98b3abb3fc67bf4292faba7e2d6 (diff) | |
download | wydawca-db5b8989ceefb9f1889219067be6d68651a4da2c.tar.gz wydawca-db5b8989ceefb9f1889219067be6d68651a4da2c.tar.bz2 |
Avoid double-checking of the directive files. Fix triplet expiration.
* doc/wydawca.texi: Document the default value for file-sweep-time.
* src/config.c (parse_single_statmask): Remove the invert pointer.
(parse_statmask): Reflect the above.
(config_finish): Ensure safe value for file_sweep_time.
* src/triplet.c (register_file): Initialize the directive_verified
member.
(triplet_expired_p): No special handling for ttl==0.
* src/verify.c (verify_directive_file): Cache the result in
trp->directive_verified.
* src/wydawca.c (file_sweep_time): Initialize to DEFAULT_FILE_SWEEP_TIME.
* src/wydawca.h (DEFAULT_FILE_SWEEP_TIME): New constant.
(DIRECTIVE_UNCHECKED,DIRECTIVE_GOOD)
(DIRECTIVE_BAD): New constants.
(struct wy_triplet): New member: directive_verified.
* tests/cwdrepl.c: Fix a prematurely closed comment.
-rw-r--r-- | doc/wydawca.texi | 2 | ||||
-rw-r--r-- | src/config.c | 42 | ||||
-rw-r--r-- | src/triplet.c | 6 | ||||
-rw-r--r-- | src/verify.c | 24 | ||||
-rw-r--r-- | src/wydawca.c | 2 | ||||
-rw-r--r-- | src/wydawca.h | 10 | ||||
-rw-r--r-- | tests/cwdrepl.c | 2 |
7 files changed, 48 insertions, 40 deletions
diff --git a/doc/wydawca.texi b/doc/wydawca.texi index 721e026..64a6e36 100644 --- a/doc/wydawca.texi +++ b/doc/wydawca.texi @@ -993,13 +993,13 @@ severely impairs performance. Set the default umask. The @var{value} argument must be an octal number. @end deffn @deffn {Config} file-sweep-time time Consider triplet expired if its oldest file was created more than @var{time} seconds ago. @xref{time interval specification}, for the -syntax of @var{time}. +syntax of @var{time}. Default is 300 seconds. This parameter may also be set for each spool individually. @xref{spool, file-sweep-time}. @end deffn @anchor{gpg-homedir} diff --git a/src/config.c b/src/config.c index 3be3a00..9d78ed3 100644 --- a/src/config.c +++ b/src/config.c @@ -356,14 +356,14 @@ static struct keyword stat_tab[] = { { "symlinks", WY_STAT_SYMLINKS }, { "rmsymlinks", WY_STAT_RMSYMLINKS }, { NULL }, }; static int -parse_single_statmask(grecs_locus_t * locus, const grecs_value_t * val, - unsigned long *pmask, int *invert) +parse_single_statmask(grecs_locus_t *locus, const grecs_value_t *val, + unsigned long *pmask) { const char *arg; int x; if (val->type != GRECS_TYPE_STRING) { grecs_error(&val->locus, 0, @@ -371,67 +371,54 @@ parse_single_statmask(grecs_locus_t * locus, const grecs_value_t * val, return 1; } arg = val->v.string; if (strcmp(arg, "all") == 0) { - *pmask = WY_STAT_MASK_ALL; - *invert = 1; + *pmask |= WY_STAT_MASK_ALL; return 0; } else if (strcmp(arg, "none") == 0) { - *pmask = WY_STAT_MASK_NONE; - *invert = 0; + *pmask &= ~WY_STAT_MASK_ALL; return 0; } if (keyword_to_tok(arg, stat_tab, CASE_SENSITIVE, &x)) { grecs_error(&val->locus, 0, _("unknown statistics type: %s"), arg); return 1; } - *pmask = WY_STAT_MASK(x); + *pmask |= WY_STAT_MASK(x); return 0; } static int -parse_statmask(grecs_locus_t * loc, grecs_value_t * val, - unsigned long *pmask) +parse_statmask(grecs_locus_t *loc, grecs_value_t *val, unsigned long *pmask) { int err = 0; - int invert = 0; - unsigned long mask = 0; + unsigned long mask = *pmask; int i; struct grecs_list_entry *ep; switch (val->type) { case GRECS_TYPE_STRING: - err = parse_single_statmask(loc, val, &mask, &invert); + err = parse_single_statmask(loc, val, &mask); break; case GRECS_TYPE_ARRAY: for (i = 0; i < val->v.arg.c; i++) { - unsigned long x; - if (parse_single_statmask(loc, val->v.arg.v[i], &x, &invert)) + if (parse_single_statmask(loc, val->v.arg.v[i], &mask)) { err = 1; - else if (invert) - mask &= ~x; - else - mask |= x; + } } break; case GRECS_TYPE_LIST: for (ep = val->v.list->head; ep; ep = ep->next) { const grecs_value_t *vp = ep->data; - unsigned long x; - if (parse_single_statmask(loc, vp, &x, &invert)) + if (parse_single_statmask(loc, vp, &mask)) err = 1; - else if (invert) - mask &= ~x; - else - mask |= x; } break; } if (!err) *pmask = mask; return err; @@ -1733,7 +1720,14 @@ config_finish(struct grecs_node *tree) } } err = 0; if (for_each_spool(create_spool_dirs, &err) || err) exit(EX_CONFIG); + + if (file_sweep_time <= 0) { + file_sweep_time = DEFAULT_FILE_SWEEP_TIME; + wy_log(LOG_NOTICE, + _("file-sweep-time too low; reverting to the default %ds"), + file_sweep_time); + } } diff --git a/src/triplet.c b/src/triplet.c index 2ad4e1d..bde3c14 100644 --- a/src/triplet.c +++ b/src/triplet.c @@ -273,12 +273,13 @@ register_file(struct file_info *finfo, struct spool *spool) grecs_alloc_die(); free(key.name); ret->file[finfo->type] = *finfo; triplet_list_lock(&triplet_pending_list); if (install) { + ret->directive_verified = DIRECTIVE_UNCHECKED; ret->spool = spool; ret->acc = grecs_txtacc_create(); } else if (ret->list) triplet_list_unlink(ret->list, ret); triplet_list_ordered_insert(&triplet_pending_list, ret); triplet_list_unlock(&triplet_pending_list); @@ -322,13 +323,13 @@ enum triplet_state { }; static enum triplet_state check_triplet_state(struct wy_triplet *trp) { if (trp->file[file_directive].name) { - if (verify_directive_file(trp)) + if (verify_directive_file(trp) != DIRECTIVE_GOOD) return triplet_bad; if (trp->file[file_dist].name == 0 && trp->file[file_signature].name == 0) { if (directive_get_value(trp, "filename", NULL)) return triplet_directive; @@ -476,15 +477,12 @@ triplet_expired_p(struct wy_triplet *trp) if (!trp) return 0; now = time(NULL); ttl = trp->spool->file_sweep_time; - if (ttl == 0) - return 0; - for (i = 0; i < FILE_TYPE_COUNT; i++) { if (trp->file[i].name && (now - trp->file[i].sb.st_mtime) >= ttl) { wy_debug(1, (_("file %s expired"), trp->file[i].name)); return 1; } } diff --git a/src/verify.c b/src/verify.c index ebdc399..39626f3 100644 --- a/src/verify.c +++ b/src/verify.c @@ -174,37 +174,45 @@ uploader_find_frp(struct wy_user *list, const char *fpr) for (; list; list = list->next) if (list->fpr && strcmp(list->fpr, fpr) == 0) break; return list; } -int -verify_directive_file(struct wy_triplet *trp) +static int +real_verify_directive_file(struct wy_triplet *trp) { if (!trp->file[file_directive].name) - return 1; + return DIRECTIVE_UNCHECKED; if (fill_project_name(trp)) - return 1; + return DIRECTIVE_BAD; if (!wy_triplet_get_uploaders(trp)) - return 1; + return DIRECTIVE_BAD; if (verify_directive_signature(trp)) { /*FIXME: Update stats */ wy_log(LOG_ERR, _("invalid signature for %s"), trp->name ? trp->name : "[unknown]"); - return 1; + return DIRECTIVE_BAD; } else wy_debug(1, (_("%s: directive file signature OK"), trp->name)); if (wy_debug_level > 1) { int i; for (i = 0; trp->directive[i]; i++) wy_log(LOG_DEBUG, "directive[%d] = %s", i, trp->directive[i]); } if (verify_directive_format(trp)) - return 1; + return DIRECTIVE_BAD; - return 0; + return DIRECTIVE_GOOD; +} + +int +verify_directive_file(struct wy_triplet *trp) +{ + if (trp->directive_verified == DIRECTIVE_UNCHECKED) + trp->directive_verified = real_verify_directive_file(trp); + return trp->directive_verified; } diff --git a/src/wydawca.c b/src/wydawca.c index 58f87ce..01ef56c 100644 --- a/src/wydawca.c +++ b/src/wydawca.c @@ -30,13 +30,13 @@ int wy_debug_level; int wy_dry_run; int wy_log_to_stderr = -1; /* -1 means autodetect */ int wy_log_facility = LOG_LOCAL1; char *wy_syslog_tag = "wydawca"; int syslog_include_prio; /* syslog messages include priority */ unsigned long print_stats; /* Print final statistics output */ -time_t file_sweep_time = 0; +time_t file_sweep_time = DEFAULT_FILE_SWEEP_TIME; char *tar_command_name = "tar"; int archive_signatures = 1; /* Archive sig files by default */ int lint_mode; int wy_mode = WY_MODE_NORMAL; diff --git a/src/wydawca.h b/src/wydawca.h index 467daa0..90a886e 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -57,13 +57,13 @@ #ifndef O_SEARCH # define O_SEARCH 0 #endif #define SP(s) ((s) ? (s) : "NONE") -#define WYDAWCA_EX_AGAIN 1 +#define DEFAULT_FILE_SWEEP_TIME 300 /* The range of directive versions we accept (major * 100 + minor) */ #define MIN_DIRECTIVE_VERSION 101 #define MAX_DIRECTIVE_VERSION 102 /* Default modes for mkdir and creat commands: rely on the umask value */ @@ -168,17 +168,25 @@ struct file_info { enum file_type type; /* Part type */ char *name; /* File name */ unsigned root_len; /* Length of root part in name */ struct stat sb; }; +/* Values for the triplet directive_verified member */ +enum { + DIRECTIVE_UNCHECKED = -1, + DIRECTIVE_GOOD = 0, + DIRECTIVE_BAD = 1 +}; + /* File triplet */ struct wy_triplet { char *name; /* Triplet base name */ struct file_info file[FILE_TYPE_COUNT]; /* Components */ unsigned version; /* Protocol version */ + int directive_verified; /* Directive file verification result */ struct spool *spool; /* Owning spool */ char *relative_dir; /* Directory relative to spool->dest_dir */ char **directive; /* Decoded directive pairs (key: value\0) */ char *blurb; /* Block of directives: directive[i] points here */ char *tmp; /* Temporary storage */ diff --git a/tests/cwdrepl.c b/tests/cwdrepl.c index 9394520..85ee4ad 100644 --- a/tests/cwdrepl.c +++ b/tests/cwdrepl.c @@ -37,13 +37,13 @@ LICENSE This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ + with this program. If not, see <http://www.gnu.org/licenses/>. HISTORY 2017-06-07 The program appeared in the GNU mailutils testsuite (see commit 453cd17f7a4be5ceaa8411a8a3ebd9fddd88df8e). 2019-11-29 Make sure the longest possible match is replaced. |