use a binary search for checking the gopher type file extensions - gopher-validator - Simple gopher menu validator. HTML git clone git://bitreich.org/gopher-validator git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gopher-validator DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit a230aa92f5f19ff3160fd7cdc7acc2810a02839a DIR parent d2d0e95268db4d42a56e0b8967af42b146a3a7e3 HTML Author: Hiltjo Posthuma <hiltjo@codemadness.org> Date: Fri, 18 Feb 2022 14:27:52 +0100 use a binary search for checking the gopher type file extensions ... and improve a check which shouldve been outside the loop. Diffstat: M gopher-validator.c | 35 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) --- DIR diff --git a/gopher-validator.c b/gopher-validator.c @@ -133,6 +133,13 @@ warning(const char *fmt, ...) } int +gophertypecmp(const void *v1, const void *v2) +{ + return strcasecmp(((struct gophertype *)v1)->ext, + ((struct gophertype *)v2)->ext); +} + +int isvalidhost(const char *s) { int colons; @@ -220,6 +227,7 @@ edial(const char *host, const char *port) void checkdir(FILE *fp) { + struct gophertype gt, *rgt; struct visited v; char line[1024], *end, *s; size_t linenr; @@ -333,21 +341,18 @@ checkdir(FILE *fp) } } - /* check type with file extension */ - if ((s = strrchr(v.path, '.')) && !strchr(s, '/')) { - s++; - for (i = 0; i < sizeof(types) / sizeof(*types); i++) { - if (primarytype == 'h' && - !strncmp(v.path, "URL:", sizeof("URL:") - 1)) - continue; - - if (!strcasecmp(s, types[i].ext) && - !strchr(types[i].allow, primarytype)) { - warning("%zu: invalid type '%c' for extension '%s', valid types: '%s'\n", - linenr, primarytype, types[i].ext, types[i].allow); - break; - } - } + /* check type with file extension, unless it is the HTML 'h' + type with a "URL:" prefix */ + if ((s = strrchr(v.path, '.')) && !strchr(s, '/') && + !(primarytype == 'h' && !strncmp(v.path, "URL:", sizeof("URL:") - 1))) { + gt.ext = ++s; + if (!(rgt = bsearch(>, &types, sizeof(types) / sizeof(types[0]), + sizeof(types[0]), &gophertypecmp))) + continue; + + if (!strchr(rgt->allow, primarytype)) + warning("%zu: invalid type '%c' for extension '%s', valid types: '%s'\n", + linenr, primarytype, rgt->ext, rgt->allow); } if (!isvalidhost(v.host))