From 7d3418e9c715e70d86c81452639a5ef239a22f31 Mon Sep 17 00:00:00 2001 From: Jose Marcial Vieira Bisneto Date: Thu, 12 Jan 2017 18:45:44 -0300 Subject: [PATCH] Added MINGW support for compiling in Windows * Still need a fix for missing libresolv. --- dnslink/dnslink.c | 244 +++++++++++++++++++++-------------- flatfs/flatfs.c | 5 +- main/main.c | 27 ++++ os/utils.c | 14 +- repo/fsrepo/fs_repo.c | 4 + repo/fsrepo/lmdb_datastore.c | 4 + repo/init.c | 4 + 7 files changed, 202 insertions(+), 100 deletions(-) diff --git a/dnslink/dnslink.c b/dnslink/dnslink.c index c88125f..1ced40a 100644 --- a/dnslink/dnslink.c +++ b/dnslink/dnslink.c @@ -46,9 +46,49 @@ Expect these resolutions: #include #include -#include -#include -#include +#ifdef __MINGW32__ + #include + + #define u_char unsigned char + #define u_int16_t uint16_t + #define u_int32_t uint32_t + #define NS_MAXDNAME 1025 /*%< maximum domain name */ + #define ns_c_in 1 + #define ns_t_txt 16 + + typedef enum __ns_sect { + ns_s_qd = 0, /*%< Query: Question. */ + ns_s_zn = 0, /*%< Update: Zone. */ + ns_s_an = 1, /*%< Query: Answer. */ + ns_s_pr = 1, /*%< Update: Prerequisites. */ + ns_s_ns = 2, /*%< Query: Name servers. */ + ns_s_ud = 2, /*%< Update: Update. */ + ns_s_ar = 3, /*%< Query|Update: Additional records. */ + ns_s_max = 4 + } ns_sect; + + typedef struct __ns_msg { + const unsigned char *_msg, *_eom; + u_int16_t _id, _flags, _counts[ns_s_max]; + const unsigned char *_sections[ns_s_max]; + ns_sect _sect; + int _rrnum; + const unsigned char *_msg_ptr; + } ns_msg; + + typedef struct __ns_rr { + char name[NS_MAXDNAME]; + u_int16_t type; + u_int16_t rr_class; + u_int32_t ttl; + u_int16_t rdlength; + const u_char * rdata; + } ns_rr; +#else + #include + #include + #include +#endif #include "ipfs/namesys/namesys.h" #define IPFS_DNSLINK_C #include "ipfs/dnslink/dnslink.h" @@ -57,65 +97,71 @@ Expect these resolutions: int ipfs_dns (int argc, char **argv) { - int err, r=0, i; - char **txt, *path, *param; - - if (argc == 4 && strcmp ("-r", argv[2])==0) { - r = 1; - argc--; argv++; - } - - if (argc != 3) { - fprintf (stderr, "usage: ipfs dns [-r] dns.name.com\n"); +#ifdef __MINGW32__ + fprintf (stderr, "Sorry, dns has not yet been implemented for the Windows version.\n"); return -1; } +#else + int err, r=0, i; + char **txt, *path, *param; - param = malloc (strlen (argv[2]) + 1); - if (!param) { - fprintf (stderr, "memory allocation failed.\n"); - return 1; - } - strcpy (param, argv[2]); - - for (i = 0 ; i < DefaultDepthLimit ; i++) { - if (memcmp(param, "/ipns/", 6) == 0) { - err = ipfs_dnslink_resolv_lookupTXT (&txt, param+6); - } else { - err = ipfs_dnslink_resolv_lookupTXT (&txt, param); - } - if (err) { - fprintf (stderr, "dns lookupTXT: %s\n", Err[err]); - return err; + if (argc == 4 && strcmp ("-r", argv[2])==0) { + r = 1; + argc--; argv++; } - err = ipfs_dnslink_parse_txt(&path, *txt); - if (err) { + if (argc != 3) { + fprintf (stderr, "usage: ipfs dns [-r] dns.name.com\n"); + return -1; + } + + param = malloc (strlen (argv[2]) + 1); + if (!param) { + fprintf (stderr, "memory allocation failed.\n"); + return 1; + } + strcpy (param, argv[2]); + + for (i = 0 ; i < DefaultDepthLimit ; i++) { + if (memcmp(param, "/ipns/", 6) == 0) { + err = ipfs_dnslink_resolv_lookupTXT (&txt, param+6); + } else { + err = ipfs_dnslink_resolv_lookupTXT (&txt, param); + } + if (err) { + fprintf (stderr, "dns lookupTXT: %s\n", Err[err]); + return err; + } + + err = ipfs_dnslink_parse_txt(&path, *txt); + if (err) { + free (*txt); + free (txt); + fprintf (stderr, "dns parse_txt: %s\n", Err[err]); + return err; + } + free (*txt); free (txt); - fprintf (stderr, "dns parse_txt: %s\n", Err[err]); - return err; - } + free (param); - free (*txt); - free (txt); - free (param); + if (! r) { + // not recursive. + break; + } - if (! r) { - // not recursive. - break; - } + if (memcmp(path, "/ipfs/", 6) == 0) { + break; + } - if (memcmp(path, "/ipfs/", 6) == 0) { - break; - } + param = path; + } while (--r); + fprintf (stdout, "%s\n", path); + free (path); - param = path; - } while (--r); - fprintf (stdout, "%s\n", path); - free (path); - - return 0; -} + return 0; + } +#endif // MINGW // ipfs_dnslink_resolve resolves the dnslink at a particular domain. It will // recursively keep resolving until reaching the defaultDepth of Resolver. If @@ -190,56 +236,58 @@ int ipfs_dnslink_resolve_n (char **p, char *d, int depth) return ErrResolveLimit; } -// lookup using libresolv -lresolv -int ipfs_dnslink_resolv_lookupTXT(char ***txt, char *domain) -{ - char buf[4096], *p; - int responseLength; - int i, l, n = 0; - ns_msg query_parse_msg; - ns_rr query_parse_rr; - u_char responseByte[4096]; +#ifndef __MINGW32__ + // lookup using libresolv -lresolv + int ipfs_dnslink_resolv_lookupTXT(char ***txt, char *domain) + { + char buf[4096], *p; + int responseLength; + int i, l, n = 0; + ns_msg query_parse_msg; + ns_rr query_parse_rr; + u_char responseByte[4096]; - // Use res_query from libresolv to retrieve TXT record from DNS server. - if ((responseLength = res_query(domain,ns_c_in,ns_t_txt,responseByte,sizeof(responseByte))) < 0 || - ns_initparse(responseByte,responseLength,&query_parse_msg) < 0) { - return ErrResolveFailed; - } else { - l = sizeof (buf); - buf[--l] = '\0'; - p = buf; - // save every TXT record to buffer separating with a \0 - for (i=0 ; i < ns_msg_count(query_parse_msg,ns_s_an) ; i++) { - if (ns_parserr(&query_parse_msg,ns_s_an,i,&query_parse_rr)) { - return ErrResolveFailed; - } else { - char *rdata = ns_rr_rdata(query_parse_rr); - memcpy(p, rdata+1, *rdata); // first byte is record length - p += *rdata; // update pointer - *p++ = '\0'; // mark end-of-record and update pointer to next record. - n++; // update record count + // Use res_query from libresolv to retrieve TXT record from DNS server. + if ((responseLength = res_query(domain,ns_c_in,ns_t_txt,responseByte,sizeof(responseByte))) < 0 || + ns_initparse(responseByte,responseLength,&query_parse_msg) < 0) { + return ErrResolveFailed; + } else { + l = sizeof (buf); + buf[--l] = '\0'; + p = buf; + // save every TXT record to buffer separating with a \0 + for (i=0 ; i < ns_msg_count(query_parse_msg,ns_s_an) ; i++) { + if (ns_parserr(&query_parse_msg,ns_s_an,i,&query_parse_rr)) { + return ErrResolveFailed; + } else { + char *rdata = ns_rr_rdata(query_parse_rr); + memcpy(p, rdata+1, *rdata); // first byte is record length + p += *rdata; // update pointer + *p++ = '\0'; // mark end-of-record and update pointer to next record. + n++; // update record count + } + } + // allocate array for all records + NULL pointer terminator. + *txt = calloc(n+1, sizeof(void*)); + if (!*txt) { + return ErrAllocFailed; + } + l = p - buf; // length of all records in buffer. + p = malloc(l); // allocate memory that will be used as string data at *txt array. + if (!p) { + free(*txt); + *txt = NULL; + return ErrAllocFailed; + } + memcpy(p, buf, l); // transfer from buffer to allocated memory. + for (i = 0 ; i < n ; i++) { + *txt[i] = p; // save position of current record at *txt array. + p = memchr(p, '\0', l - (p - *txt[0])) + 1; // find next record position after next \0 } } - // allocate array for all records + NULL pointer terminator. - *txt = calloc(n+1, sizeof(void*)); - if (!*txt) { - return ErrAllocFailed; - } - l = p - buf; // length of all records in buffer. - p = malloc(l); // allocate memory that will be used as string data at *txt array. - if (!p) { - free(*txt); - *txt = NULL; - return ErrAllocFailed; - } - memcpy(p, buf, l); // transfer from buffer to allocated memory. - for (i = 0 ; i < n ; i++) { - *txt[i] = p; // save position of current record at *txt array. - p = memchr(p, '\0', l - (p - *txt[0])) + 1; // find next record position after next \0 - } + return 0; } - return 0; -} +#endif // ipfs_dnslink_resolve_once implements resolver. int ipfs_dnslink_resolve_once (char ***p, char *domain) @@ -257,11 +305,13 @@ int ipfs_dnslink_resolve_once (char ***p, char *domain) return ErrInvalidDomain; } +#ifndef __MINGW32__ if (!ipfs_dnslink_lookup_txt) { // if not set ipfs_dnslink_lookup_txt = ipfs_dnslink_resolv_lookupTXT; // use default libresolv } err = ipfs_dnslink_lookup_txt (&txt, domain); +#endif if (err) { return err; } diff --git a/flatfs/flatfs.c b/flatfs/flatfs.c index fe06dba..0d1101b 100644 --- a/flatfs/flatfs.c +++ b/flatfs/flatfs.c @@ -50,8 +50,11 @@ int ipfs_flatfs_create_directory(const char* full_directory) { return 0; } // it is not there, create it +#ifdef __MINGW32__ + if (mkdir(full_directory) == -1) +#else if (mkdir(full_directory, S_IRWXU) == -1) - return 0; +#endif return 0; return 1; } diff --git a/main/main.c b/main/main.c index 1958b34..b0c1a63 100644 --- a/main/main.c +++ b/main/main.c @@ -6,6 +6,33 @@ #include "ipfs/importer/exporter.h" #include "ipfs/dnslink/dnslink.h" +#ifdef __MINGW32__ + void bzero(void *s, size_t n) + { + memset (s, '\0', n); + } + + char *strtok_r(char *str, const char *delim, char **save) + { + char *res, *last; + + if( !save ) + return strtok(str, delim); + if( !str && !(str = *save) ) + return NULL; + last = str + strlen(str); + if( (*save = res = strtok(str, delim)) ) + { + *save += strlen(res); + if( *save < last ) + (*save)++; + else + *save = NULL; + } + return res; + } +#endif // MINGW + void stripit(int argc, char** argv) { char tmp[strlen(argv[argc])]; strcpy(tmp, &argv[argc][1]); diff --git a/os/utils.c b/os/utils.c index 76e162a..4ba8443 100644 --- a/os/utils.c +++ b/os/utils.c @@ -1,9 +1,12 @@ #include "ipfs/os/utils.h" +#include #include #include #include -#include +#ifndef __MINGW32__ + #include +#endif #include #include #include @@ -25,7 +28,11 @@ char* os_utils_getenv(const char* variable) { * @returns true(1) on success */ int os_utils_setenv(const char* variable, const char* value, int overwrite) { - return setenv(variable, value, overwrite); +#ifdef __MINGW32__ + return 0; +#else + setenv(variable, value, overwrite); +#endif } /** @@ -33,8 +40,11 @@ int os_utils_setenv(const char* variable, const char* value, int overwrite) { * @returns the home directory */ char* os_utils_get_homedir() { +#ifndef __MINGW32__ struct passwd *pw = getpwuid(getuid()); return pw->pw_dir; +#endif + return "."; } /** diff --git a/repo/fsrepo/fs_repo.c b/repo/fsrepo/fs_repo.c index 57f901a..aa80b54 100644 --- a/repo/fsrepo/fs_repo.c +++ b/repo/fsrepo/fs_repo.c @@ -482,7 +482,11 @@ int ipfs_repo_fsrepo_blockstore_init(const struct FSRepo* fs_repo) { if (retVal == 0) return 0; +#ifdef __MINGW32__ + if (mkdir(full_path) != 0) +#else if (mkdir(full_path, S_IRWXU) != 0) +#endif return 0; return 1; } diff --git a/repo/fsrepo/lmdb_datastore.c b/repo/fsrepo/lmdb_datastore.c index 1bcd5a9..663897e 100644 --- a/repo/fsrepo/lmdb_datastore.c +++ b/repo/fsrepo/lmdb_datastore.c @@ -183,6 +183,10 @@ int repo_fsrepo_lmdb_cast(struct Datastore* datastore) { * @returns true(1) on success */ int repo_fsrepo_lmdb_create_directory(struct Datastore* datastore) { +#ifdef __MINGW32__ + return mkdir(datastore->path) == 0; +#else return mkdir(datastore->path, S_IRWXU) == 0; +#endif } diff --git a/repo/init.c b/repo/init.c index a3c4b34..49db57f 100644 --- a/repo/init.c +++ b/repo/init.c @@ -74,7 +74,11 @@ int ipfs_repo_init(int argc, char** argv) { return 0; } // make the directory +#ifdef __MINGW32__ + if (mkdir(dir) == -1) { +#else if (mkdir(dir, S_IRWXU) == -1) { +#endif printf("Unable to create the directory: %s\n", dir); return 0; }