diff --git a/CMakeLists.txt b/CMakeLists.txt index 6db18269b..a8e646d06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,13 +21,30 @@ STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_V STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}") SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}") +IF (AMIGA) + # Default AmigaOS to use the PowerPC SHA1 + SET(SHA1_TYPE "ppc") +ENDIF() + # Find required dependencies INCLUDE_DIRECTORIES(src include deps/http-parser) FILE(GLOB SRC_HTTP deps/http-parser/*.c) +# Specify sha1 implementation +IF (SHA1_TYPE STREQUAL "ppc") + ADD_DEFINITIONS(-DPPC_SHA1) + FILE(GLOB SRC_SHA1 src/ppc/*.c src/ppc/*.S) +ELSE () + SET (SRC_SHA1) +ENDIF() + IF (NOT WIN32) FIND_PACKAGE(ZLIB) + IF (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") + INCLUDE_DIRECTORIES(deps/regex) + SET(SRC_REGEX deps/regex/regex.c) + ENDIF() ELSE() # Windows doesn't understand POSIX regex on its own INCLUDE_DIRECTORIES(deps/regex) @@ -115,12 +132,15 @@ IF (WIN32 AND NOT CYGWIN) FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c src/compat/*.c) ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c src/compat/*.c) +ELSEIF (AMIGA) + ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R) + FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/amiga/*.c src/compat/*.c) ELSE() FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c) ENDIF () # Compile and link libgit2 -ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${WIN_RC}) +ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC}) IF (WIN32) TARGET_LINK_LIBRARIES(git2 ws2_32) diff --git a/examples/network/Makefile b/examples/network/Makefile index c21869ac9..298b1dc86 100644 --- a/examples/network/Makefile +++ b/examples/network/Makefile @@ -2,7 +2,7 @@ default: all CC = gcc CFLAGS += -g -CFLAGS += -I../../include -L../../ -lgit2 -lpthread +CFLAGS += -I../../include -L../../build -lgit2 -lpthread OBJECTS = \ git2.o \ diff --git a/examples/network/fetch.c b/examples/network/fetch.c index 8dcb81b1f..d2752124d 100644 --- a/examples/network/fetch.c +++ b/examples/network/fetch.c @@ -91,6 +91,7 @@ int fetch(git_repository *repo, int argc, char **argv) usleep(10000); printf("\rReceived %d/%d objects in %d bytes", stats.processed, stats.total, bytes); } while (!data.finished); + printf("\rReceived %d/%d objects in %d bytes\n", stats.processed, stats.total, bytes); // Disconnect the underlying connection to prevent from idling. diff --git a/include/git2/common.h b/include/git2/common.h index 0e9379804..1af045cff 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -55,6 +55,10 @@ #define GIT_WIN32 1 #endif +#ifdef __amigaos4__ +#include +#endif + /** * @file git2/common.h * @brief Git common platform definitions diff --git a/include/git2/errors.h b/include/git2/errors.h index ccbc9fcf4..b4809fe15 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -20,6 +20,7 @@ GIT_BEGIN_DECL #ifdef GIT_OLD_ERRORS enum { GIT_SUCCESS = 0, + GIT_ERROR = -1, GIT_ENOTOID = -2, GIT_ENOTFOUND = -3, GIT_ENOMEM = -4, @@ -52,7 +53,7 @@ enum { GIT_ENOMATCH = -31, GIT_ESHORTBUFFER = -32, }; -#endif +#else /** Generic return codes */ enum { @@ -66,6 +67,7 @@ enum { GIT_PASSTHROUGH = -30, GIT_REVWALKOVER = -31, }; +#endif typedef struct { char *message; diff --git a/include/git2/types.h b/include/git2/types.h index b4b48afa3..691903005 100644 --- a/include/git2/types.h +++ b/include/git2/types.h @@ -32,6 +32,9 @@ GIT_BEGIN_DECL * stat() functions, for all platforms. */ #include +#ifdef __amigaos4__ +#include +#endif #if defined(_MSC_VER) diff --git a/src/amiga/map.c b/src/amiga/map.c new file mode 100755 index 000000000..2fb065c8b --- /dev/null +++ b/src/amiga/map.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009-2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#include + +#ifndef GIT_WIN32 + +#include "posix.h" +#include "map.h" +#include + +int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset) +{ + GIT_MMAP_VALIDATE(out, len, prot, flags); + + out->data = NULL; + out->len = 0; + + if ((prot & GIT_PROT_WRITE) && ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)) { + giterr_set(GITERR_OS, "Trying to map shared-writeable"); + return -1; + } + + if((out->data = malloc(len))) { + p_lseek(fd, offset, SEEK_SET); + p_read(fd, out->data, len); + } + + if (!out->data || (out->data == MAP_FAILED)) { + giterr_set(GITERR_OS, "Failed to mmap. Could not write data"); + return -1; + } + + out->len = len; + + return 0; +} + +int p_munmap(git_map *map) +{ + assert(map != NULL); + free(map->data); + + return 0; +} + +#endif + diff --git a/src/indexer.c b/src/indexer.c index 5ae66c9f1..565d9ea0e 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -365,11 +365,11 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz if (error < 0) { idx->off = entry_start; error = store_delta(idx); + if (error == GIT_EBUFS) return 0; if (error < 0) return error; - continue; } diff --git a/src/map.h b/src/map.h index 96d879547..6ce6d3685 100644 --- a/src/map.h +++ b/src/map.h @@ -23,6 +23,10 @@ #define GIT_MAP_TYPE 0xf #define GIT_MAP_FIXED 0x10 +#ifdef __amigaos4__ +#define MAP_FAILED 0 +#endif + typedef struct { /* memory mapped buffer */ void *data; /* data bytes */ size_t len; /* data length */ diff --git a/src/mwindow.c b/src/mwindow.c index 57adabd48..74fbf7834 100644 --- a/src/mwindow.c +++ b/src/mwindow.c @@ -158,6 +158,7 @@ static git_mwindow *new_window( git_mwindow *w; w = git__malloc(sizeof(*w)); + if (w == NULL) return NULL; diff --git a/src/netops.c b/src/netops.c index 32554743f..0342d7fa1 100644 --- a/src/netops.c +++ b/src/netops.c @@ -32,6 +32,99 @@ #include "buffer.h" #include "transport.h" +#ifdef NO_ADDRINFO +struct addrinfo { + struct hostent *ai_hostent; + struct servent *ai_servent; + struct sockaddr_in ai_addr_in; + struct sockaddr *ai_addr; + size_t ai_addrlen; + int ai_family; + int ai_socktype; + int ai_protocol; + long ai_port; + struct addrinfo *ai_next; +}; + +static int getaddrinfo(const char *host, const char *port, struct addrinfo *hints, struct addrinfo **info) { + GIT_UNUSED(hints); + + struct addrinfo *ainfo, *ai; + int p = 0; + + if((ainfo = malloc(sizeof(struct addrinfo))) == NULL) + return -1; + + if((ainfo->ai_hostent = gethostbyname(host)) == NULL) + return -2; + + ainfo->ai_servent = getservbyname(port, 0); + + if(ainfo->ai_servent) + ainfo->ai_port = ainfo->ai_servent->s_port; + else + ainfo->ai_port = atol(port); + + + memcpy(&ainfo->ai_addr_in.sin_addr, ainfo->ai_hostent->h_addr_list[0], ainfo->ai_hostent->h_length); + ainfo->ai_protocol = 0; + ainfo->ai_socktype = hints->ai_socktype; + ainfo->ai_family = ainfo->ai_hostent->h_addrtype; + ainfo->ai_addr_in.sin_family = ainfo->ai_family; + ainfo->ai_addr_in.sin_port = ainfo->ai_port; + ainfo->ai_addr = (struct addrinfo *)&ainfo->ai_addr_in; + ainfo->ai_addrlen = sizeof(struct sockaddr_in); + + *info = ainfo; + + if(ainfo->ai_hostent->h_addr_list[1] == NULL) { + ainfo->ai_next = NULL; + return 0; + } + + ai = ainfo; + + for (p = 1; ainfo->ai_hostent->h_addr_list[p] != NULL; p++) { + ai->ai_next = malloc(sizeof(struct addrinfo)); + memcpy(&ai->ai_next, ainfo, sizeof(struct addrinfo)); + memcpy(&ai->ai_next->ai_addr_in.sin_addr, ainfo->ai_hostent->h_addr_list[p], ainfo->ai_hostent->h_length); + ai->ai_next->ai_addr = (struct addrinfo *)&ai->ai_next->ai_addr_in; + ai = ai->ai_next; + } + + ai->ai_next = NULL; + return 0; +} + +static void freeaddrinfo(struct addrinfo *info) { + struct addrinfo *p, *next; + + p = info; + + while(p != NULL) { + next = p->ai_next; + free(p); + p = next; + } +} + +static const char *gai_strerror(int ret) { + switch(ret) { + case -1: + return "Out of memory"; + break; + + case -2: + return "Address lookup failed"; + break; + + default: + return "Unknown error"; + break; + } +} +#endif + #ifdef GIT_WIN32 static void net_set_error(const char *str) { @@ -381,8 +474,8 @@ int gitno_connect(git_transport *t, const char *host, const char *port) GIT_SOCKET s = INVALID_SOCKET; memset(&hints, 0x0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; if ((ret = getaddrinfo(host, port, &hints, &info)) < 0) { giterr_set(GITERR_NET, "Failed to resolve address for %s: %s", host, gai_strerror(ret)); @@ -391,6 +484,7 @@ int gitno_connect(git_transport *t, const char *host, const char *port) for (p = info; p != NULL; p = p->ai_next) { s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (s == INVALID_SOCKET) { net_set_error("error creating socket"); break; diff --git a/src/pack.c b/src/pack.c index 0db1069de..9b5e0e18f 100644 --- a/src/pack.c +++ b/src/pack.c @@ -262,7 +262,7 @@ int git_packfile_unpack_header( if (base == NULL) return GIT_EBUFS; - ret = packfile_unpack_header1(&used, size_p, type_p, base, left); + ret = packfile_unpack_header1(&used, size_p, type_p, base, left); git_mwindow_close(w_curs); if (ret == GIT_EBUFS) return ret; diff --git a/src/pool.c b/src/pool.c index 641292d06..63bf09cee 100644 --- a/src/pool.c +++ b/src/pool.c @@ -275,6 +275,8 @@ uint32_t git_pool__system_page_size(void) SYSTEM_INFO info; GetSystemInfo(&info); size = (uint32_t)info.dwPageSize; +#elif defined(__amigaos4__) + size = (uint32_t)4096; /* 4K as there is no global value we can query */ #else size = (uint32_t)sysconf(_SC_PAGE_SIZE); #endif diff --git a/src/posix.h b/src/posix.h index 5799c0499..d423b7e07 100644 --- a/src/posix.h +++ b/src/posix.h @@ -83,6 +83,16 @@ extern int p_gettimeofday(struct timeval *tv, struct timezone *tz); # include "unix/posix.h" #endif +#ifndef NO_READDIR_R #define p_readdir_r(d,e,r) readdir_r(d,e,r) +#else +#include +GIT_INLINE(int) p_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) +{ + GIT_UNUSED(entry); + *result = readdir(dirp); + return 0; +} +#endif #endif diff --git a/src/unix/map.c b/src/unix/map.c index 772f4e247..9dcae5845 100644 --- a/src/unix/map.c +++ b/src/unix/map.c @@ -33,6 +33,7 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs mflag = MAP_PRIVATE; out->data = mmap(NULL, len, mprot, mflag, fd, offset); + if (!out->data || out->data == MAP_FAILED) { giterr_set(GITERR_OS, "Failed to mmap. Could not write data"); return -1; @@ -47,6 +48,7 @@ int p_munmap(git_map *map) { assert(map != NULL); munmap(map->data, map->len); + return 0; } diff --git a/src/unix/posix.h b/src/unix/posix.h index 48b492941..83fd8a189 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_posix__w32_h__ #define INCLUDE_posix__w32_h__ -#ifndef __sun +#if !defined(__sun) && !defined(__amigaos4__) # include # define p_fnmatch(p, s, f) fnmatch(p, s, f) #else