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