Line | Count | Source |
1 | | #include "basics.h" |
2 | | #include "reftable-fsck.h" |
3 | | #include "reftable-table.h" |
4 | | #include "stack.h" |
5 | | |
6 | | static bool table_has_valid_name(const char *name) |
7 | 0 | { |
8 | 0 | const char *ptr = name; |
9 | 0 | char *endptr; |
10 | | |
11 | | /* strtoull doesn't set errno on success */ |
12 | 0 | errno = 0; |
13 | |
|
14 | 0 | strtoull(ptr, &endptr, 16); |
15 | 0 | if (errno) |
16 | 0 | return false; |
17 | 0 | ptr = endptr; |
18 | |
|
19 | 0 | if (*ptr != '-') |
20 | 0 | return false; |
21 | 0 | ptr++; |
22 | |
|
23 | 0 | strtoull(ptr, &endptr, 16); |
24 | 0 | if (errno) |
25 | 0 | return false; |
26 | 0 | ptr = endptr; |
27 | |
|
28 | 0 | if (*ptr != '-') |
29 | 0 | return false; |
30 | 0 | ptr++; |
31 | |
|
32 | 0 | strtoul(ptr, &endptr, 16); |
33 | 0 | if (errno) |
34 | 0 | return false; |
35 | 0 | ptr = endptr; |
36 | |
|
37 | 0 | if (strcmp(ptr, ".ref") && strcmp(ptr, ".log")) |
38 | 0 | return false; |
39 | | |
40 | 0 | return true; |
41 | 0 | } |
42 | | |
43 | | typedef int (*table_check_fn)(struct reftable_table *table, |
44 | | reftable_fsck_report_fn report_fn, |
45 | | void *cb_data); |
46 | | |
47 | | static int table_check_name(struct reftable_table *table, |
48 | | reftable_fsck_report_fn report_fn, |
49 | | void *cb_data) |
50 | 0 | { |
51 | 0 | if (!table_has_valid_name(table->name)) { |
52 | 0 | struct reftable_fsck_info info; |
53 | |
|
54 | 0 | info.error = REFTABLE_FSCK_ERROR_TABLE_NAME; |
55 | 0 | info.msg = "invalid reftable table name"; |
56 | 0 | info.path = table->name; |
57 | |
|
58 | 0 | return report_fn(&info, cb_data); |
59 | 0 | } |
60 | | |
61 | 0 | return 0; |
62 | 0 | } |
63 | | |
64 | | static int table_checks(struct reftable_table *table, |
65 | | reftable_fsck_report_fn report_fn, |
66 | | reftable_fsck_verbose_fn verbose_fn UNUSED, |
67 | | void *cb_data) |
68 | 0 | { |
69 | 0 | table_check_fn table_check_fns[] = { |
70 | 0 | table_check_name, |
71 | 0 | NULL, |
72 | 0 | }; |
73 | 0 | int err = 0; |
74 | |
|
75 | 0 | for (size_t i = 0; table_check_fns[i]; i++) |
76 | 0 | err |= table_check_fns[i](table, report_fn, cb_data); |
77 | |
|
78 | 0 | return err; |
79 | 0 | } |
80 | | |
81 | | int reftable_fsck_check(struct reftable_stack *stack, |
82 | | reftable_fsck_report_fn report_fn, |
83 | | reftable_fsck_verbose_fn verbose_fn, |
84 | | void *cb_data) |
85 | 0 | { |
86 | 0 | struct reftable_buf msg = REFTABLE_BUF_INIT; |
87 | 0 | int err = 0; |
88 | |
|
89 | 0 | for (size_t i = 0; i < stack->tables_len; i++) { |
90 | 0 | reftable_buf_reset(&msg); |
91 | 0 | reftable_buf_addstr(&msg, "Checking table: "); |
92 | 0 | reftable_buf_addstr(&msg, stack->tables[i]->name); |
93 | 0 | verbose_fn(msg.buf, cb_data); |
94 | |
|
95 | 0 | err |= table_checks(stack->tables[i], report_fn, verbose_fn, cb_data); |
96 | 0 | } |
97 | |
|
98 | 0 | reftable_buf_release(&msg); |
99 | 0 | return err; |
100 | 0 | } |