diff --git a/include/ipfs/namesys/namesys.h b/include/ipfs/namesys/namesys.h index 6fedbd0..ef6fda6 100644 --- a/include/ipfs/namesys/namesys.h +++ b/include/ipfs/namesys/namesys.h @@ -82,6 +82,10 @@ int IsTLD (char *s); int IsDomain (char *s); + typedef struct s_DNSResolver { + // TODO + } DNSResolver; + int DNSResolverResolveOnce (DNSResolver *r, char **path, char *name); int workDomain (int output, DNSResolver *r, char *name); int parseEntry (char **Path, char *txt); diff --git a/include/ipfs/path/path.h b/include/ipfs/path/path.h index a305938..f2a97c1 100644 --- a/include/ipfs/path/path.h +++ b/include/ipfs/path/path.h @@ -1,16 +1,20 @@ #ifndef IPFS_PATH_H #define IPFS_PATH_H - char *ErrPath[] = { - NULL, - // ErrBadPath is returned when a given path is incorrectly formatted - "invalid 'ipfs ref' path", - // Paths after a protocol must contain at least one component - "path must contain at least one component", - "TODO: ErrCidDecode", - NULL, - "no link named %s under %s" - }; + #ifdef IPFS_PATH_C + char *ErrPath[] = { + NULL, + // ErrBadPath is returned when a given path is incorrectly formatted + "invalid 'ipfs ref' path", + // Paths after a protocol must contain at least one component + "path must contain at least one component", + "TODO: ErrCidDecode", + NULL, + "no link named %s under %s" + }; + #else + extern char **ErrPath; + #endif // IPFS_PATH_C enum { ErrBadPath = 1, diff --git a/namesys/dns.c b/namesys/dns.c index 3ed6a90..454bc1b 100644 --- a/namesys/dns.c +++ b/namesys/dns.c @@ -68,13 +68,6 @@ int DNSResolverResolveOnce (char **path, char *name) return ErrPipe; } - dnslink = malloc(strlen(domain) + sizeof(dlprefix)); - if (!dnslink) { - return ErrAllocFailed; - } - strcpy (dnslink, dlprefix); - strcat (dnslink, domain); - r = fork(); switch(r) { case -1: @@ -90,6 +83,14 @@ int DNSResolverResolveOnce (char **path, char *name) return ErrPipe; case 0: // child close(p2[STDIN_FILENO]); // we don't need to read at child process. + + dnslink = malloc(strlen(domain) + sizeof(dlprefix)); + if (!dnslink) { + return ErrAllocFailed; + } + strcpy (dnslink, dlprefix); + strcat (dnslink, domain); + return workDomain (p2[STDOUT_FILENO], r, dnslink); } close(p2[STDOUT_FILENO]); // we don't need to write at main process. diff --git a/namesys/proquint.c b/namesys/proquint.c index a68f90f..1ff47a6 100644 --- a/namesys/proquint.c +++ b/namesys/proquint.c @@ -1,18 +1,175 @@ #include +#include +#include #include "ipfs/namesys/namesys.h" #include "ipfs/cid/cid.h" #include "ipfs/path/path.h" +const uint8_t conse[] = {'b', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'z'}; +const uint8_t vowse[] = {'a', 'i', 'o', 'u'}; + +// Find decoded number from the encoded consonant. +static inline int consd(char c) +{ + int i; + + for (i = 0 ; i < sizeof(conse) ; i++) { + if (c == conse[i]) { + return i; + } + } + + return 0; +} + +// Find decoded number of encoded vowel. +static inline int vowsd(char c) +{ + int i; + + for (i = 0 ; i < sizeof(vowse) ; i++) { + if (c == vowse[i]) { + return i; + } + } + + return 0; +} + +/** +* Tests if a given string is a Proquint identifier +* +* @param {string} str The candidate string. +* +* @return {bool} Whether or not it qualifies. +* @return {error} Error +*/ +int ProquintIsProquint(char *str) +{ + int i, c; + + // if str is null, or length isn't 11 or don't have - at middle + if (!str || strlen(str) != 11 || str[5] != '-') { + return 0; // it's not a proquint + } + + // run every position + for (i = 0 ; i < 11 ; i++) { + if (i == 5) i++; // skip -, already tested. + switch (i) { + case 1: + case 3: + case 7: + case 9: + // compare with vowse array + c = vowsd(str[i]); + if (str[i] != vowse[c]) { + return 0; // it's not a proquint + } + break; + default: // 0,2,4,6,8,10 + // compare with conse array + c = consd(str[i]); + if (str[i] != conse[c]) { + return 0; // it's not a proquint + } + } + } + + return 1; // passed on every value. +} + +/** +* Encodes an arbitrary byte slice into an identifier. +* +* @param {[]byte} buf Slice of bytes to encode. +* +* @return {string} The given byte slice as an identifier. +*/ +char *ProquintEncode(char *buf) +{ + char *ret; + int i, c; + uint16_t n; + + if (!buf) { + return NULL; + } + + ret = malloc(12); + if (!ret) { + return NULL; + } + + for (i = 0, c = 0; i < 4; i += 2) { + n = ((buf[i] & 0xff) << 8) | (buf[i + 1] & 0xff); + + ret[c++] = conse[(n >> 12) & 0x0f]; + ret[c++] = vowse[(n >> 10) & 0x03]; + ret[c++] = conse[(n >> 6) & 0x0f]; + ret[c++] = vowse[(n >> 4) & 0x03]; + ret[c++] = conse[n & 0x0f]; + ret[c++] = '-'; + } + ret[--c] = '\0'; + + return ret; +} + +/** +* Decodes an identifier into its corresponding byte slice. +* +* @param {string} str Identifier to convert. +* +* @return {[]byte} The identifier as a byte slice. +*/ +char *ProquintDecode(char *str) +{ + char *ret; + int i, c; + uint16_t x; + + // make sure its a valid Proquint string. + if (!ProquintIsProquint(str)) { + return NULL; + } + + ret = malloc(4); + if (!ret) { + return NULL; + } + + for (i = 0, c = 0 ; i < 11 ; i += 6) { + x =(consd(str[i + 0]) << 12) | \ + (vowsd(str[i + 1]) << 10) | \ + (consd(str[i + 2]) << 6) | \ + (vowsd(str[i + 3]) << 4) | \ + (consd(str[i + 4]) << 0); + + ret[c++] = x >> 8; + ret[c++] = x & 0xff; + } + + return ret; +} + // resolveOnce implements resolver. Decodes the proquint string. int ProquintResolveOnce (char **p, char *name) { - int err = proquintIsProquint(name); + int err = ProquintIsProquint(name); + char buf[500]; if (err) { *p = NULL; err = ErrInvalidProquint; } else { - err = pathFromString(p, proquintDecode(name)); + err = ParsePath(buf, ProquintDecode(name)); + if (!err) { + *p = malloc (strlen(buf) + 1); + if (p) { + strcpy(*p, buf); + } + } } return err; } diff --git a/namesys/proquint_test.c b/namesys/proquint_test.c new file mode 100644 index 0000000..559e60d --- /dev/null +++ b/namesys/proquint_test.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include + +int ProquintIsProquint(char *str); +char *ProquintEncode(char *buf); +char *ProquintDecode(char *str); + +int main(void) { + char *r, *s; + int i; + char *p[] = {"lusab-babad", "gutih-tugad", "gutuk-bisog", "mudof-sakat", + "haguz-biram", "mabiv-gibot", "natag-lisaf", "tibup-zujah", + "tobog-higil", "todah-vobij", "sinid-makam", "budov-kuras", + NULL}; + + for (i = 0 ; p[i] ; i++) { + r = ProquintDecode (p[i]); + if (r) { + struct in_addr ip_addr; + memcpy (&(ip_addr.s_addr), r, sizeof(ip_addr.s_addr)); + printf ("%s\t%s", p[i], inet_ntoa(ip_addr)); + s = ProquintEncode(r); + free (r); + if (s) { + printf ("\t%s", s); + free (s); + } + printf("\n"); + } + } + return 0; +} diff --git a/path/path.c b/path/path.c index 75b71b7..21bfc4a 100644 --- a/path/path.c +++ b/path/path.c @@ -1,6 +1,7 @@ #include #include #include +#define IPFS_PATH_C #include // FromCid safely converts a cid.Cid type to a Path type @@ -43,7 +44,7 @@ char** SplitN (char *p, char *delim, int n) r = calloc(sizeof(char*), n + 1); // splits plus NULL pointer termination if (!r) { - free(r); + free(rbuf); return NULL; }