summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fsck.c76
-rw-r--r--fsck.h9
2 files changed, 80 insertions, 5 deletions
diff --git a/fsck.c b/fsck.c
index 30c1a19aa5..41208a412a 100644
--- a/fsck.c
+++ b/fsck.c
@@ -108,13 +108,79 @@ static int fsck_msg_type(enum fsck_msg_id msg_id,
{
int msg_type;
- msg_type = msg_id_info[msg_id].msg_type;
- if (options->strict && msg_type == FSCK_WARN)
- msg_type = FSCK_ERROR;
+ assert(msg_id >= 0 && msg_id < FSCK_MSG_MAX);
+
+ if (options->msg_type)
+ msg_type = options->msg_type[msg_id];
+ else {
+ msg_type = msg_id_info[msg_id].msg_type;
+ if (options->strict && msg_type == FSCK_WARN)
+ msg_type = FSCK_ERROR;
+ }
return msg_type;
}
+static int parse_msg_type(const char *str)
+{
+ if (!strcmp(str, "error"))
+ return FSCK_ERROR;
+ else if (!strcmp(str, "warn"))
+ return FSCK_WARN;
+ else
+ die("Unknown fsck message type: '%s'", str);
+}
+
+void fsck_set_msg_type(struct fsck_options *options,
+ const char *msg_id, const char *msg_type)
+{
+ int id = parse_msg_id(msg_id), type;
+
+ if (id < 0)
+ die("Unhandled message id: %s", msg_id);
+ type = parse_msg_type(msg_type);
+
+ if (!options->msg_type) {
+ int i;
+ int *msg_type = xmalloc(sizeof(int) * FSCK_MSG_MAX);
+ for (i = 0; i < FSCK_MSG_MAX; i++)
+ msg_type[i] = fsck_msg_type(i, options);
+ options->msg_type = msg_type;
+ }
+
+ options->msg_type[id] = type;
+}
+
+void fsck_set_msg_types(struct fsck_options *options, const char *values)
+{
+ char *buf = xstrdup(values), *to_free = buf;
+ int done = 0;
+
+ while (!done) {
+ int len = strcspn(buf, " ,|"), equal;
+
+ done = !buf[len];
+ if (!len) {
+ buf++;
+ continue;
+ }
+ buf[len] = '\0';
+
+ for (equal = 0;
+ equal < len && buf[equal] != '=' && buf[equal] != ':';
+ equal++)
+ buf[equal] = tolower(buf[equal]);
+ buf[equal] = '\0';
+
+ if (equal == len)
+ die("Missing '=': '%s'", buf);
+
+ fsck_set_msg_type(options, buf, buf + equal + 1);
+ buf += len + 1;
+ }
+ free(to_free);
+}
+
__attribute__((format (printf, 4, 5)))
static int report(struct fsck_options *options, struct object *object,
enum fsck_msg_id id, const char *fmt, ...)
@@ -604,6 +670,10 @@ int fsck_object(struct object *obj, void *data, unsigned long size,
int fsck_error_function(struct object *obj, int msg_type, const char *message)
{
+ if (msg_type == FSCK_WARN) {
+ warning("object %s: %s", sha1_to_hex(obj->sha1), message);
+ return 0;
+ }
error("object %s: %s", sha1_to_hex(obj->sha1), message);
return 1;
}
diff --git a/fsck.h b/fsck.h
index f6f268aa72..af3c84e878 100644
--- a/fsck.h
+++ b/fsck.h
@@ -6,6 +6,10 @@
struct fsck_options;
+void fsck_set_msg_type(struct fsck_options *options,
+ const char *msg_id, const char *msg_type);
+void fsck_set_msg_types(struct fsck_options *options, const char *values);
+
/*
* callback function for fsck_walk
* type is the expected type of the object or OBJ_ANY
@@ -25,10 +29,11 @@ struct fsck_options {
fsck_walk_func walk;
fsck_error error_func;
unsigned strict:1;
+ int *msg_type;
};
-#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0 }
-#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1 }
+#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0, NULL }
+#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1, NULL }
/* descend in all linked child objects
* the return value is: