diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kike.c | 87 |
1 files changed, 87 insertions, 0 deletions
@@ -89,6 +89,93 @@ setup_signal_handlers (void) } } +// --- IRC token validation ---------------------------------------------------- + +enum validation_result +{ + VALIDATION_OK, + VALIDATION_ERROR_EMPTY, + VALIDATION_ERROR_TOO_LONG, + VALIDATION_ERROR_INVALID +}; + +// Everything as per RFC 2812 +#define IRC_NICKNAME_MAX 9 +#define IRC_HOSTNAME_MAX 63 + +// Anything to keep it as short as possible +#define SN "[0-9A-Za-z][-0-9A-Za-z]*[0-9A-Za-z]*" +#define N4 "[0-9]{1,3}" +#define N6 "[0-9ABCDEFabcdef]{1,}" + +#define LE "A-Za-z" +#define SP "\\[\\]\\\\`_^{|}" + +static const char * +irc_validate_to_str (enum validation_result result) +{ + switch (result) + { + case VALIDATION_OK: return "success"; + case VALIDATION_ERROR_EMPTY: return "the value is empty"; + case VALIDATION_ERROR_INVALID: return "invalid format"; + case VALIDATION_ERROR_TOO_LONG: return "the value is too long"; + default: abort (); + } +} + +// TODO: at least cache the resulting `regex_t' in a `struct str_map' + +static enum validation_result +irc_validate_hostname (const char *hostname) +{ + if (!*hostname) + return VALIDATION_ERROR_EMPTY; + if (!regex_match ("^" SN "(\\." SN ")*$", hostname, NULL)) + return VALIDATION_ERROR_INVALID; + if (strlen (hostname) > IRC_HOSTNAME_MAX) + return VALIDATION_ERROR_TOO_LONG; + return VALIDATION_OK; +} + +static bool +irc_is_valid_hostaddr (const char *hostaddr) +{ + if (regex_match ("^" N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL) + || regex_match ("^" N6 ":" N6 ":" N6 ":" N6 ":" + N6 ":" N6 ":" N6 ":" N6 "$", hostaddr, NULL) + || regex_match ("^0:0:0:0:0:(0|[Ff]{4}):" + N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL)) + return true; + return false; +} + +static bool +irc_is_valid_host (const char *host) +{ + return irc_validate_hostname (host) == VALIDATION_OK + || irc_is_valid_hostaddr (host); +} + +static bool +irc_validate_nickname (const char *nickname) +{ + if (!*nickname) + return VALIDATION_ERROR_EMPTY; + if (!regex_match ("^[" LE SP "][-0-9" LE SP "]*$", nickname, NULL)) + return VALIDATION_ERROR_INVALID; + if (strlen (nickname) > IRC_NICKNAME_MAX) + return VALIDATION_ERROR_TOO_LONG; + return VALIDATION_OK; +} + +#undef SN +#undef N4 +#undef N6 + +#undef LE +#undef SP + // --- Application data -------------------------------------------------------- enum |