diff options
-rw-r--r-- | src/gpg.c | 3 | ||||
-rw-r--r-- | src/stat.c | 160 | ||||
-rw-r--r-- | src/triplet.c | 17 | ||||
-rw-r--r-- | src/verify.c | 18 | ||||
-rw-r--r-- | src/wydawca.c | 12 | ||||
-rw-r--r-- | src/wydawca.h | 1 | ||||
-rw-r--r-- | tests/dry_run01.at | 2 | ||||
-rw-r--r-- | tests/upload01.at | 2 |
8 files changed, 192 insertions, 23 deletions
@@ -121,10 +121,11 @@ static void | |||
121 | remove_homedir(void) | 121 | remove_homedir(void) |
122 | { | 122 | { |
123 | wy_debug(2, (_("removing GNUPG home directory: %s"), temp_homedir)); | 123 | wy_debug(2, (_("removing GNUPG home directory: %s"), temp_homedir)); |
124 | if (rmdir_r(temp_homedir)) | 124 | if (rmdir_r(temp_homedir)) { |
125 | wy_log(LOG_CRIT, _("failed to remove GPG directory %s"), | 125 | wy_log(LOG_CRIT, _("failed to remove GPG directory %s"), |
126 | temp_homedir); | 126 | temp_homedir); |
127 | } | 127 | } |
128 | } | ||
128 | 129 | ||
129 | /* Create a temporary GPG home directory */ | 130 | /* Create a temporary GPG home directory */ |
130 | static int | 131 | static int |
diff --git a/src/stat.c b/src/stat.c new file mode 100644 index 0000000..da885f6 --- /dev/null +++ b/src/stat.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* wydawca - automatic release submission daemon | ||
2 | Copyright (C) 2008-2013, 2017, 2019-2020 Sergey Poznyakoff | ||
3 | |||
4 | Wydawca is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU General Public License as published by the | ||
6 | Free Software Foundation; either version 3 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | Wydawca is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License along | ||
15 | with wydawca. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #include <wydawca.h> | ||
18 | |||
19 | /* Cumulative statistic counters */ | ||
20 | static WY_STAT_COUNTER global_stats[WY_MAX_STAT]; | ||
21 | pthread_mutex_t global_stats_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
22 | pthread_cond_t global_stats_cond = PTHREAD_COND_INITIALIZER; | ||
23 | static int stat_stop; | ||
24 | pthread_t stat_tid; | ||
25 | |||
26 | void | ||
27 | wydawca_stat_add(int what, size_t n) | ||
28 | { | ||
29 | if (what >= WY_MAX_STAT) abort(); | ||
30 | pthread_mutex_lock(&global_stats_mutex); | ||
31 | global_stats[what] += n; | ||
32 | pthread_mutex_unlock(&global_stats_mutex); | ||
33 | } | ||
34 | |||
35 | void | ||
36 | wydawca_stat_notify(int final) | ||
37 | { | ||
38 | void *ret; | ||
39 | pthread_mutex_lock(&global_stats_mutex); | ||
40 | stat_stop = final; | ||
41 | pthread_cond_broadcast(&global_stats_cond); | ||
42 | pthread_mutex_unlock(&global_stats_mutex); | ||
43 | if (final) | ||
44 | pthread_join(stat_tid, &ret); | ||
45 | } | ||
46 | |||
47 | static void | ||
48 | stat_reset(void) | ||
49 | { | ||
50 | int i; | ||
51 | |||
52 | for (i = 0; i < WY_MAX_STAT; i++) | ||
53 | global_stats[i] = 0; | ||
54 | } | ||
55 | |||
56 | struct micronent stat_report_schedule; | ||
57 | |||
58 | static void stat_log(void); | ||
59 | static void stat_reset(void); | ||
60 | |||
61 | void * | ||
62 | wy_thr_stat(void *ptr) | ||
63 | { | ||
64 | wy_set_cur_thread_name("WY_stat"); | ||
65 | pthread_mutex_lock(&global_stats_mutex); | ||
66 | while (!stat_stop) { | ||
67 | struct timespec ts; | ||
68 | micron_next_time(&stat_report_schedule, &ts); | ||
69 | pthread_cond_timedwait(&global_stats_cond, &global_stats_mutex, &ts); | ||
70 | stat_log(); | ||
71 | notify_stat(); | ||
72 | stat_reset(); | ||
73 | } | ||
74 | pthread_mutex_unlock(&global_stats_mutex); | ||
75 | return NULL; | ||
76 | } | ||
77 | |||
78 | void | ||
79 | wydawca_stat_init(void) | ||
80 | { | ||
81 | pthread_create(&stat_tid, NULL, wy_thr_stat, NULL); | ||
82 | } | ||
83 | |||
84 | static char *stat_name[WY_MAX_STAT] = { | ||
85 | N_("errors"), | ||
86 | N_("warnings"), | ||
87 | N_("bad signatures"), | ||
88 | N_("access violation attempts"), | ||
89 | N_("complete triplets"), | ||
90 | N_("incomplete triplets"), | ||
91 | N_("bad triplets"), | ||
92 | N_("expired triplets"), | ||
93 | N_("triplet successes"), | ||
94 | N_("files uploaded"), | ||
95 | N_("files archived"), | ||
96 | N_("symlinks created"), | ||
97 | N_("symlinks removed"), | ||
98 | N_("check failures"), | ||
99 | }; | ||
100 | |||
101 | static char *stat_kwname[WY_MAX_STAT] = { | ||
102 | "stat:errors", | ||
103 | "stat:warnings", | ||
104 | "stat:bad_signatures", | ||
105 | "stat:access_violations", | ||
106 | "stat:complete_triplets", | ||
107 | "stat:incomplete_triplets", | ||
108 | "stat:bad_triplets", | ||
109 | "stat:expired_triplets", | ||
110 | "stat:triplet_success", | ||
111 | "stat:uploads", | ||
112 | "stat:archives", | ||
113 | "stat:symlinks", | ||
114 | "stat:rmsymlinks", | ||
115 | "stat:check_failures" | ||
116 | }; | ||
117 | |||
118 | int | ||
119 | wy_stat_mask_p(unsigned long mask) | ||
120 | { | ||
121 | int i; | ||
122 | |||
123 | for (i = 0; i < WY_MAX_STAT; i++) | ||
124 | if (global_stats[i] != 0 && (mask && WY_STAT_MASK(i))) | ||
125 | return 1; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | int | ||
130 | wy_stat_expansion(char **ret, char const *name, size_t len) | ||
131 | { | ||
132 | int i; | ||
133 | |||
134 | for (i = 0; i < WY_MAX_STAT; i++) { | ||
135 | if (strlen(stat_kwname[i]) == len | ||
136 | && memcmp(stat_kwname[i], name, len) == 0) { | ||
137 | size_t size = 0; | ||
138 | *ret = NULL; | ||
139 | if (grecs_asprintf(ret, &size, "%u", global_stats[i])) | ||
140 | return WRDSE_NOSPACE; | ||
141 | else | ||
142 | return WRDSE_OK; | ||
143 | } | ||
144 | } | ||
145 | return WRDSE_UNDEF; | ||
146 | } | ||
147 | |||
148 | static void | ||
149 | stat_log(void) | ||
150 | { | ||
151 | int i; | ||
152 | |||
153 | if (wy_stat_mask_p(print_stats)) { | ||
154 | for (i = 0; i < WY_MAX_STAT; i++) | ||
155 | if (print_stats & WY_STAT_MASK(i)) | ||
156 | wy_log(LOG_INFO, "%s: %u", | ||
157 | gettext(stat_name[i]), global_stats[i]); | ||
158 | } | ||
159 | } | ||
160 | |||
diff --git a/src/triplet.c b/src/triplet.c index 138a979..0da254e 100644 --- a/src/triplet.c +++ b/src/triplet.c | |||
@@ -383,11 +383,13 @@ remove_triplet_unlocked(struct wy_triplet *trp) | |||
383 | if (trp->file[i].name) { | 383 | if (trp->file[i].name) { |
384 | if (!wy_dry_run) { | 384 | if (!wy_dry_run) { |
385 | if (unlinkat(trp->spool->source_fd, trp->file[i].name, 0)) { | 385 | if (unlinkat(trp->spool->source_fd, trp->file[i].name, 0)) { |
386 | if (errno != ENOENT) | 386 | if (errno != ENOENT) { |
387 | wydawca_stat_incr(WY_STAT_ERRORS); | ||
387 | wy_log(LOG_ERR, | 388 | wy_log(LOG_ERR, |
388 | _("cannot remove %s/%s: %s"), | 389 | _("cannot remove %s/%s: %s"), |
389 | trp->spool->source_dir, | 390 | trp->spool->source_dir, |
390 | trp->file[i].name, strerror(errno)); | 391 | trp->file[i].name, strerror(errno)); |
392 | } | ||
391 | } else | 393 | } else |
392 | wy_log(LOG_NOTICE, _("removing %s/%s"), | 394 | wy_log(LOG_NOTICE, _("removing %s/%s"), |
393 | trp->spool->source_dir, trp->file[i].name); | 395 | trp->spool->source_dir, trp->file[i].name); |
@@ -417,7 +419,8 @@ triplet_commit(struct wy_triplet *trp) | |||
417 | { | 419 | { |
418 | if (spool_open_dictionaries(trp->spool) == 0) { | 420 | if (spool_open_dictionaries(trp->spool) == 0) { |
419 | wy_debug(1, (_("processing triplet `%s'"), trp->name)); | 421 | wy_debug(1, (_("processing triplet `%s'"), trp->name)); |
420 | process_directives(trp); | 422 | if (process_directives(trp)) |
423 | wydawca_stat_incr(WY_STAT_ERRORS); | ||
421 | } | 424 | } |
422 | } | 425 | } |
423 | 426 | ||
@@ -535,6 +538,7 @@ static void wy_ws_error(const char *fmt, ...); | |||
535 | static inline void | 538 | static inline void |
536 | report_failed_string(char const *str, size_t len) | 539 | report_failed_string(char const *str, size_t len) |
537 | { | 540 | { |
541 | wydawca_stat_incr(WY_STAT_ERRORS); | ||
538 | if (len > 32) | 542 | if (len > 32) |
539 | wy_log(LOG_ERR, _("failed to expand string %16.16s...%16.16s"), | 543 | wy_log(LOG_ERR, _("failed to expand string %16.16s...%16.16s"), |
540 | str, str + len - 16); | 544 | str, str + len - 16); |
@@ -1036,6 +1040,7 @@ wy_triplet_get_uploaders(struct wy_triplet *trp) | |||
1036 | rc = dictionary_lookup(dict, md, command); | 1040 | rc = dictionary_lookup(dict, md, command); |
1037 | free(command); | 1041 | free(command); |
1038 | if (rc) { | 1042 | if (rc) { |
1043 | wydawca_stat_incr(WY_STAT_ERRORS); | ||
1039 | wy_log(LOG_ERR, _("cannot get uploaders for %s"), trp->name); | 1044 | wy_log(LOG_ERR, _("cannot get uploaders for %s"), trp->name); |
1040 | dictionary_close(dict, md); | 1045 | dictionary_close(dict, md); |
1041 | return NULL; | 1046 | return NULL; |
@@ -1043,6 +1048,7 @@ wy_triplet_get_uploaders(struct wy_triplet *trp) | |||
1043 | 1048 | ||
1044 | nrows = dictionary_num_rows(dict); | 1049 | nrows = dictionary_num_rows(dict); |
1045 | if (nrows == 0) { | 1050 | if (nrows == 0) { |
1051 | wydawca_stat_incr(WY_STAT_ERRORS); | ||
1046 | wy_log(LOG_ERR, _("found no uploaders for %s"), trp->name); |