forked from agorise/c-ipfs
123 lines
2.8 KiB
C
123 lines
2.8 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <time.h>
|
|
#include "ipfs/namesys/namesys.h"
|
|
#include "ipfs/namesys/isdomain.h"
|
|
|
|
void ipfs_isdomain_to_upper(char *dst, char *src)
|
|
{
|
|
while(*src) {
|
|
*dst++ = toupper(*src++);
|
|
}
|
|
*dst = '\0';
|
|
}
|
|
|
|
int ipfs_isdomain_has_suffix (char *s, char *suf)
|
|
{
|
|
char *p;
|
|
|
|
p = s + strlen(s) - strlen(suf);
|
|
return strcmp(p, suf) == 0;
|
|
}
|
|
|
|
int ipfs_isdomain_is_at_array(tlds *a, char *s)
|
|
{
|
|
char str[strlen(s)+1];
|
|
|
|
ipfs_isdomain_to_upper(str, s);
|
|
while(a->str) {
|
|
if (strcmp(a->str, str) == 0) {
|
|
return a->condition;
|
|
}
|
|
a++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ipfs_isdomain_match_string (char *d)
|
|
{
|
|
char str[strlen(d)+1], *p = str, *l;
|
|
|
|
ipfs_isdomain_to_upper(str, d);
|
|
|
|
// l point to last two chars.
|
|
l = p + strlen(p) - 2;
|
|
|
|
// can't start with a dot
|
|
if (*p == '.') {
|
|
return 0; // invalid
|
|
}
|
|
|
|
// last 2 chars can't be a dot or a number.
|
|
if ((*l >= 'A' && *l <= 'Z') && (l[1] >= 'A' && l[1] <= 'Z')) {
|
|
while (*p) {
|
|
if ((*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == '-') {
|
|
p++;
|
|
} else {
|
|
return 0; // invalid
|
|
}
|
|
}
|
|
} else {
|
|
return 0; // invalid
|
|
}
|
|
|
|
return 1; // valid
|
|
}
|
|
|
|
// ipfs_isdomain_is_icann_tld returns whether the given string is a TLD (Top Level Domain),
|
|
// according to ICANN. Well, really according to the TLDs listed in this
|
|
// package.
|
|
int ipfs_isdomain_is_icann_tld(char *s)
|
|
{
|
|
return ipfs_isdomain_is_at_array (TLDs, s);
|
|
}
|
|
|
|
// ipfs_isdomain_is_extended_tld returns whether the given string is a TLD (Top Level Domain),
|
|
// extended with a few other "TLDs", .bit, .onion
|
|
int ipfs_isdomain_is_extended_tld (char *s)
|
|
{
|
|
return ipfs_isdomain_is_at_array (ExtendedTLDs, s);
|
|
}
|
|
|
|
// ipfs_isdomain_is_tld returns whether the given string is a TLD (according to ICANN, or
|
|
// in the set of ExtendedTLDs listed in this package.
|
|
int ipfs_isdomain_is_tld (char *s)
|
|
{
|
|
return ipfs_isdomain_is_icann_tld (s) || ipfs_isdomain_is_extended_tld(s);
|
|
}
|
|
|
|
// ipfs_isdomain_is_domain returns whether given string is a domain.
|
|
// It first checks the TLD, and then uses a regular expression.
|
|
int ipfs_isdomain_is_domain (char *s)
|
|
{
|
|
int err;
|
|
char *str, *tld;
|
|
|
|
str = malloc(strlen(s) + 1);
|
|
if (!str) {
|
|
return ErrAllocFailed;
|
|
}
|
|
memcpy(str, s, strlen(s) + 1);
|
|
s = str; // work with local copy.
|
|
|
|
if (ipfs_isdomain_has_suffix (s, ".")) {
|
|
s[strlen(s) - 1] = '\0';
|
|
}
|
|
|
|
tld = strrchr(s, '.');
|
|
|
|
if (!tld) { // don't have a dot.
|
|
return 0;
|
|
}
|
|
|
|
tld++; // ignore last dot
|
|
|
|
if (!ipfs_isdomain_is_tld (tld)) {
|
|
return 0;
|
|
}
|
|
|
|
err = ipfs_isdomain_match_string(s);
|
|
free (s);
|
|
return err;
|
|
}
|