diff --git a/src/formats.c b/src/formats.c index b6fba4094c..495c916e8a 100644 --- a/src/formats.c +++ b/src/formats.c @@ -235,6 +235,27 @@ static int exclude_formats(char *rej_format, struct fmt_main **full_fmt_list) return removed; } +/* Exclusions. Drop all format(s) up to and including the matching rej_format from full list */ +static int exclude_formats_up_to(char *rej_format, struct fmt_main **full_fmt_list) +{ + static int drop = 1; + struct fmt_main *current; + int removed = 0; + + if ((current = *full_fmt_list)) + do { + if (drop) { + if (fmt_match(rej_format, current, 1)) + drop = 0; + *full_fmt_list = current->next; + removed++; + } else + break; + } while ((current = current->next)); + + return removed; +} + /* Inclusions. Move any format(s) matching req_format from full list to new list */ static int include_formats(char *req_format, struct fmt_main **full_fmt_list) { @@ -329,7 +350,7 @@ static void comma_split(struct list_main *dst, const char *src) char* fmt_type(char *name) { - if (name[1] && (name[0] == '+' || name[0] == '-')) + if (name[1] && (name[0] == '+' || name[0] == '-' || name[0] == '/')) name++; if (fmt_is_class(name)) @@ -357,9 +378,16 @@ int fmt_check_custom_list(void) fmt_list = NULL; fmt_tail = &fmt_list; - /* "-" Exclusions first, from the full list. */ + /* "-" or "/" Exclusions first, from the full list. */ do { - if (req_format->data[0] == '-') { + if (req_format->data[0] == '/') { + char *exclude_fmt = &(req_format->data[1]); + + if (!exclude_fmt[0]) + error_msg("Error: '%s' in format list doesn't make sense\n", req_format->data); + num_e += exclude_formats_up_to(exclude_fmt, &full_fmt_list); + } + else if (req_format->data[0] == '-') { char *exclude_fmt = &(req_format->data[1]); if (!exclude_fmt[0]) @@ -371,7 +399,7 @@ int fmt_check_custom_list(void) /* Inclusions. Move to the new list. */ req_format = req_formats->head; do { - if ((req_format->data[0] != '-') && (req_format->data[0] != '+')) { + if ((req_format->data[0] != '-') && (req_format->data[0] != '+') && (req_format->data[0] != '/')) { had_i = 1; if (!include_formats(req_format->data, &full_fmt_list) && !is_in_fmt_list(req_format->data)) { if (john_main_process) diff --git a/src/john.c b/src/john.c index 29d9411704..d7b90a9227 100644 --- a/src/john.c +++ b/src/john.c @@ -202,7 +202,15 @@ static int exit_status = 0; static void john_register_one(struct fmt_main *format) { if (options.format) { - if (options.format[0] == '-' && options.format[1]) { + if (options.format[0] == '/' && options.format[1]) { + static int drop = 1; + + if (drop) { + if (fmt_match(&options.format[1], format, 1)) + drop = 0; + return; + } + } else if (options.format[0] == '-' && options.format[1]) { if (fmt_match(&options.format[1], format, 1)) return; } else if (options.format[0] == '+' && options.format[1]) {