Merge branch 'md/interix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:34 +0000 (17:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Nov 2010 01:52:34 +0000 (17:52 -0800)
* md/interix:
Interix: add configure checks
add support for the SUA layer (interix; windows)

Conflicts:
git-compat-util.h

1  2 
Makefile
daemon.c
git-compat-util.h
diff --combined Makefile
index 919ed2b7ec87cb8399bb7c1119251c1704e2fbe7,c9d8c9e1fe07d687f790234694ef84641324e5e1..1d4241346594e5e0df7df7f766899d4ac76d84ff
+++ b/Makefile
@@@ -401,7 -401,6 +401,7 @@@ EXTRA_PROGRAMS 
  # ... and all the rest that could be moved out of bindir to gitexecdir
  PROGRAMS += $(EXTRA_PROGRAMS)
  
 +PROGRAM_OBJS += daemon.o
  PROGRAM_OBJS += fast-import.o
  PROGRAM_OBJS += imap-send.o
  PROGRAM_OBJS += shell.o
@@@ -497,8 -496,6 +497,8 @@@ LIB_H += compat/bswap.
  LIB_H += compat/cygwin.h
  LIB_H += compat/mingw.h
  LIB_H += compat/win32/pthread.h
 +LIB_H += compat/win32/syslog.h
 +LIB_H += compat/win32/sys/poll.h
  LIB_H += csum-file.h
  LIB_H += decorate.h
  LIB_H += delta.h
@@@ -1067,6 -1064,7 +1067,6 @@@ ifeq ($(uname_S),Windows
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
 -      NO_POSIX_ONLY_PROGRAMS = YesPlease
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
        NO_CURL = YesPlease
        NO_PYTHON = YesPlease
        BLK_SHA1 = YesPlease
 +      NO_POSIX_GOODIES = UnfortunatelyYes
        NATIVE_CRLF = YesPlease
  
        CC = compat/vcbuild/scripts/clink.pl
        AR = compat/vcbuild/scripts/lib.pl
        CFLAGS =
        BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
 -      COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o
 +      COMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o compat/win32/sys/poll.o
        COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
        BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
        EXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib
  endif
        X = .exe
  endif
+ ifeq ($(uname_S),Interix)
+       NO_SYS_POLL_H = YesPlease
+       NO_INTTYPES_H = YesPlease
+       NO_INITGROUPS = YesPlease
+       NO_IPV6 = YesPlease
+       NO_MEMMEM = YesPlease
+       NO_MKDTEMP = YesPlease
+       NO_STRTOUMAX = YesPlease
+       NO_NSEC = YesPlease
+       NO_MKSTEMPS = YesPlease
+       ifeq ($(uname_R),3.5)
+               NO_INET_NTOP = YesPlease
+               NO_INET_PTON = YesPlease
+       endif
+       ifeq ($(uname_R),5.2)
+               NO_INET_NTOP = YesPlease
+               NO_INET_PTON = YesPlease
+       endif
+ endif
  ifneq (,$(findstring MINGW,$(uname_S)))
        pathsep = ;
        NO_PREAD = YesPlease
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
 -      NO_POSIX_ONLY_PROGRAMS = YesPlease
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
        NO_PYTHON = YesPlease
        BLK_SHA1 = YesPlease
        ETAGS_TARGET = ETAGS
 +      NO_INET_PTON = YesPlease
 +      NO_INET_NTOP = YesPlease
 +      NO_POSIX_GOODIES = UnfortunatelyYes
        COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
        COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
        COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
 -              compat/win32/pthread.o
 +              compat/win32/pthread.o compat/win32/syslog.o \
 +              compat/win32/sys/poll.o
        EXTLIBS += -lws2_32
        PTHREAD_LIBS =
        X = .exe
@@@ -1252,6 -1265,9 +1271,6 @@@ ifdef ZLIB_PAT
  endif
  EXTLIBS += -lz
  
 -ifndef NO_POSIX_ONLY_PROGRAMS
 -      PROGRAM_OBJS += daemon.o
 -endif
  ifndef NO_OPENSSL
        OPENSSL_LIBSSL = -lssl
        ifdef OPENSSLDIR
@@@ -1363,6 -1379,15 +1382,15 @@@ endi
  ifdef NO_SYS_SELECT_H
        BASIC_CFLAGS += -DNO_SYS_SELECT_H
  endif
+ ifdef NO_SYS_POLL_H
+       BASIC_CFLAGS += -DNO_SYS_POLL_H
+ endif
+ ifdef NO_INTTYPES_H
+       BASIC_CFLAGS += -DNO_INTTYPES_H
+ endif
+ ifdef NO_INITGROUPS
+       BASIC_CFLAGS += -DNO_INITGROUPS
+ endif
  ifdef NO_MMAP
        COMPAT_CFLAGS += -DNO_MMAP
        COMPAT_OBJS += compat/mmap.o
@@@ -1400,11 -1425,9 +1428,11 @@@ endi
  endif
  ifdef NO_INET_NTOP
        LIB_OBJS += compat/inet_ntop.o
 +      BASIC_CFLAGS += -DNO_INET_NTOP
  endif
  ifdef NO_INET_PTON
        LIB_OBJS += compat/inet_pton.o
 +      BASIC_CFLAGS += -DNO_INET_PTON
  endif
  
  ifdef NO_ICONV
@@@ -1419,10 -1442,6 +1447,10 @@@ ifdef NO_DEFLATE_BOUN
        BASIC_CFLAGS += -DNO_DEFLATE_BOUND
  endif
  
 +ifdef NO_POSIX_GOODIES
 +      BASIC_CFLAGS += -DNO_POSIX_GOODIES
 +endif
 +
  ifdef BLK_SHA1
        SHA1_HEADER = "block-sha1/sha1.h"
        LIB_OBJS += block-sha1/sha1.o
@@@ -1936,7 -1955,7 +1964,7 @@@ git-%$X: %.o $(GITLIBS
  
  git-imap-send$X: imap-send.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 -              $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL)
 +              $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
  
  git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
diff --combined daemon.c
index 13435b46674a3a7b123597ab11751459173f3325,de59f5d13944e7475586fcb5704ea6e7d2d1dd9d..d2a4e023e895d57db798be76450b77afb2ac49be
+++ b/daemon.c
@@@ -5,6 -5,8 +5,6 @@@
  #include "strbuf.h"
  #include "string-list.h"
  
 -#include <syslog.h>
 -
  #ifndef HOST_NAME_MAX
  #define HOST_NAME_MAX 256
  #endif
  #define NI_MAXSERV 32
  #endif
  
+ #ifdef NO_INITGROUPS
+ #define initgroups(x, y) (0) /* nothing */
+ #endif
  static int log_syslog;
  static int verbose;
  static int reuseaddr;
@@@ -23,10 -29,10 +27,10 @@@ static const char daemon_usage[] 
  "           [--strict-paths] [--base-path=<path>] [--base-path-relaxed]\n"
  "           [--user-path | --user-path=<path>]\n"
  "           [--interpolated-path=<path>]\n"
 -"           [--reuseaddr] [--detach] [--pid-file=<file>]\n"
 +"           [--reuseaddr] [--pid-file=<file>]\n"
  "           [--(enable|disable|allow-override|forbid-override)=<service>]\n"
  "           [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
 -"                      [--user=<user> [--group=<group>]]\n"
 +"                      [--detach] [--user=<user> [--group=<group>]]\n"
  "           [<directory>...]";
  
  /* List of acceptable pathname prefixes */
@@@ -67,14 -73,12 +71,14 @@@ static void logreport(int priority, con
                syslog(priority, "%s", buf);
        } else {
                /*
 -               * Since stderr is set to linebuffered mode, the
 +               * Since stderr is set to buffered mode, the
                 * logging of different processes will not overlap
 +               * unless they overflow the (rather big) buffers.
                 */
                fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid());
                vfprintf(stderr, err, params);
                fputc('\n', stderr);
 +              fflush(stderr);
        }
  }
  
@@@ -516,14 -520,37 +520,14 @@@ static void parse_host_arg(char *extra_
  }
  
  
 -static int execute(struct sockaddr *addr)
 +static int execute(void)
  {
        static char line[1000];
        int pktlen, len, i;
 +      char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
  
 -      if (addr) {
 -              char addrbuf[256] = "";
 -              int port = -1;
 -
 -              if (addr->sa_family == AF_INET) {
 -                      struct sockaddr_in *sin_addr = (void *) addr;
 -                      inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
 -                      port = ntohs(sin_addr->sin_port);
 -#ifndef NO_IPV6
 -              } else if (addr && addr->sa_family == AF_INET6) {
 -                      struct sockaddr_in6 *sin6_addr = (void *) addr;
 -
 -                      char *buf = addrbuf;
 -                      *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
 -                      inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
 -                      strcat(buf, "]");
 -
 -                      port = ntohs(sin6_addr->sin6_port);
 -#endif
 -              }
 -              loginfo("Connection from %s:%d", addrbuf, port);
 -              setenv("REMOTE_ADDR", addrbuf, 1);
 -      }
 -      else {
 -              unsetenv("REMOTE_ADDR");
 -      }
 +      if (addr)
 +              loginfo("Connection from %s:%s", addr, port);
  
        alarm(init_timeout ? init_timeout : timeout);
        pktlen = packet_read_line(0, line, sizeof(line));
@@@ -593,17 -620,17 +597,17 @@@ static unsigned int live_children
  
  static struct child {
        struct child *next;
 -      pid_t pid;
 +      struct child_process cld;
        struct sockaddr_storage address;
  } *firstborn;
  
 -static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)
 +static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen)
  {
        struct child *newborn, **cradle;
  
        newborn = xcalloc(1, sizeof(*newborn));
        live_children++;
 -      newborn->pid = pid;
 +      memcpy(&newborn->cld, cld, sizeof(*cld));
        memcpy(&newborn->address, addr, addrlen);
        for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
                if (!addrcmp(&(*cradle)->address, &newborn->address))
        *cradle = newborn;
  }
  
 -static void remove_child(pid_t pid)
 -{
 -      struct child **cradle, *blanket;
 -
 -      for (cradle = &firstborn; (blanket = *cradle); cradle = &blanket->next)
 -              if (blanket->pid == pid) {
 -                      *cradle = blanket->next;
 -                      live_children--;
 -                      free(blanket);
 -                      break;
 -              }
 -}
 -
  /*
   * This gets called if the number of connections grows
   * past "max_connections".
@@@ -627,7 -667,7 +631,7 @@@ static void kill_some_child(void
  
        for (; (next = blanket->next); blanket = next)
                if (!addrcmp(&blanket->address, &next->address)) {
 -                      kill(blanket->pid, SIGTERM);
 +                      kill(blanket->cld.pid, SIGTERM);
                        break;
                }
  }
@@@ -637,28 -677,18 +641,28 @@@ static void check_dead_children(void
        int status;
        pid_t pid;
  
 -      while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
 -              const char *dead = "";
 -              remove_child(pid);
 -              if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0))
 -                      dead = " (with error)";
 -              loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
 -      }
 +      struct child **cradle, *blanket;
 +      for (cradle = &firstborn; (blanket = *cradle);)
 +              if ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {
 +                      const char *dead = "";
 +                      if (status)
 +                              dead = " (with error)";
 +                      loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
 +
 +                      /* remove the child */
 +                      *cradle = blanket->next;
 +                      live_children--;
 +                      free(blanket);
 +              } else
 +                      cradle = &blanket->next;
  }
  
 -static void handle(int incoming, struct sockaddr *addr, int addrlen)
 +static char **cld_argv;
 +static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
  {
 -      pid_t pid;
 +      struct child_process cld = { 0 };
 +      char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
 +      char *env[] = { addrbuf, portbuf, NULL };
  
        if (max_connections && live_children >= max_connections) {
                kill_some_child();
                }
        }
  
 -      if ((pid = fork())) {
 -              close(incoming);
 -              if (pid < 0) {
 -                      logerror("Couldn't fork %s", strerror(errno));
 -                      return;
 -              }
 +      if (addr->sa_family == AF_INET) {
 +              struct sockaddr_in *sin_addr = (void *) addr;
 +              inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
 +                  sizeof(addrbuf) - 12);
 +              snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
 +                  ntohs(sin_addr->sin_port));
 +#ifndef NO_IPV6
 +      } else if (addr && addr->sa_family == AF_INET6) {
 +              struct sockaddr_in6 *sin6_addr = (void *) addr;
  
 -              add_child(pid, addr, addrlen);
 -              return;
 +              char *buf = addrbuf + 12;
 +              *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
 +              inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
 +                  sizeof(addrbuf) - 13);
 +              strcat(buf, "]");
 +
 +              snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
 +                  ntohs(sin6_addr->sin6_port));
 +#endif
        }
  
 -      dup2(incoming, 0);
 -      dup2(incoming, 1);
 -      close(incoming);
 +      cld.env = (const char **)env;
 +      cld.argv = (const char **)cld_argv;
 +      cld.in = incoming;
 +      cld.out = dup(incoming);
  
 -      exit(execute(addr));
 +      if (start_command(&cld))
 +              logerror("unable to fork");
 +      else
 +              add_child(&cld, addr, addrlen);
 +      close(incoming);
  }
  
  static void child_handler(int signo)
@@@ -903,15 -918,9 +907,15 @@@ static int service_loop(struct socketli
  
                for (i = 0; i < socklist->nr; i++) {
                        if (pfd[i].revents & POLLIN) {
 -                              struct sockaddr_storage ss;
 -                              unsigned int sslen = sizeof(ss);
 -                              int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
 +                              union {
 +                                      struct sockaddr sa;
 +                                      struct sockaddr_in sai;
 +#ifndef NO_IPV6
 +                                      struct sockaddr_in6 sai6;
 +#endif
 +                              } ss;
 +                              socklen_t sslen = sizeof(ss);
 +                              int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
                                if (incoming < 0) {
                                        switch (errno) {
                                        case EAGAIN:
                                                die_errno("accept returned");
                                        }
                                }
 -                              handle(incoming, (struct sockaddr *)&ss, sslen);
 +                              handle(incoming, &ss.sa, sslen);
                        }
                }
        }
@@@ -940,62 -949,6 +944,62 @@@ static void sanitize_stdfds(void
                close(fd);
  }
  
 +#ifdef NO_POSIX_GOODIES
 +
 +struct credentials;
 +
 +static void drop_privileges(struct credentials *cred)
 +{
 +      /* nothing */
 +}
 +
 +static void daemonize(void)
 +{
 +      die("--detach not supported on this platform");
 +}
 +
 +static struct credentials *prepare_credentials(const char *user_name,
 +    const char *group_name)
 +{
 +      die("--user not supported on this platform");
 +}
 +
 +#else
 +
 +struct credentials {
 +      struct passwd *pass;
 +      gid_t gid;
 +};
 +
 +static void drop_privileges(struct credentials *cred)
 +{
 +      if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
 +          setgid (cred->gid) || setuid(cred->pass->pw_uid)))
 +              die("cannot drop privileges");
 +}
 +
 +static struct credentials *prepare_credentials(const char *user_name,
 +    const char *group_name)
 +{
 +      static struct credentials c;
 +
 +      c.pass = getpwnam(user_name);
 +      if (!c.pass)
 +              die("user not found - %s", user_name);
 +
 +      if (!group_name)
 +              c.gid = c.pass->pw_gid;
 +      else {
 +              struct group *group = getgrnam(group_name);
 +              if (!group)
 +                      die("group not found - %s", group_name);
 +
 +              c.gid = group->gr_gid;
 +      }
 +
 +      return &c;
 +}
 +
  static void daemonize(void)
  {
        switch (fork()) {
        close(2);
        sanitize_stdfds();
  }
 +#endif
  
  static void store_pid(const char *path)
  {
                die_errno("failed to write pid file '%s'", path);
  }
  
 -static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
 +static int serve(struct string_list *listen_addr, int listen_port,
 +    struct credentials *cred)
  {
        struct socketlist socklist = { NULL, 0, 0 };
  
                die("unable to allocate any listen sockets on port %u",
                    listen_port);
  
 -      if (pass && gid &&
 -          (initgroups(pass->pw_name, gid) || setgid (gid) ||
 -           setuid(pass->pw_uid)))
 -              die("cannot drop privileges");
 +      drop_privileges(cred);
  
        return service_loop(&socklist);
  }
@@@ -1043,10 -997,12 +1047,10 @@@ int main(int argc, char **argv
  {
        int listen_port = 0;
        struct string_list listen_addr = STRING_LIST_INIT_NODUP;
 -      int inetd_mode = 0;
 +      int serve_mode = 0, inetd_mode = 0;
        const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
        int detach = 0;
 -      struct passwd *pass = NULL;
 -      struct group *group;
 -      gid_t gid = 0;
 +      struct credentials *cred = NULL;
        int i;
  
        git_extract_argv0_path(argv[0]);
                                continue;
                        }
                }
 +              if (!strcmp(arg, "--serve")) {
 +                      serve_mode = 1;
 +                      continue;
 +              }
                if (!strcmp(arg, "--inetd")) {
                        inetd_mode = 1;
                        log_syslog = 1;
                set_die_routine(daemon_die);
        } else
                /* avoid splitting a message in the middle */
 -              setvbuf(stderr, NULL, _IOLBF, 0);
 +              setvbuf(stderr, NULL, _IOFBF, 4096);
  
 -      if (inetd_mode && (group_name || user_name))
 -              die("--user and --group are incompatible with --inetd");
 +      if (inetd_mode && (detach || group_name || user_name))
 +              die("--detach, --user and --group are incompatible with --inetd");
  
        if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
                die("--listen= and --port= are incompatible with --inetd");
        if (group_name && !user_name)
                die("--group supplied without --user");
  
 -      if (user_name) {
 -              pass = getpwnam(user_name);
 -              if (!pass)
 -                      die("user not found - %s", user_name);
 -
 -              if (!group_name)
 -                      gid = pass->pw_gid;
 -              else {
 -                      group = getgrnam(group_name);
 -                      if (!group)
 -                              die("group not found - %s", group_name);
 -
 -                      gid = group->gr_gid;
 -              }
 -      }
 +      if (user_name)
 +              cred = prepare_credentials(user_name, group_name);
  
        if (strict_paths && (!ok_paths || !*ok_paths))
                die("option --strict-paths requires a whitelist");
                    base_path);
  
        if (inetd_mode) {
 -              struct sockaddr_storage ss;
 -              struct sockaddr *peer = (struct sockaddr *)&ss;
 -              socklen_t slen = sizeof(ss);
 -
                if (!freopen("/dev/null", "w", stderr))
                        die_errno("failed to redirect stderr to /dev/null");
 -
 -              if (getpeername(0, peer, &slen))
 -                      peer = NULL;
 -
 -              return execute(peer);
        }
  
 +      if (inetd_mode || serve_mode)
 +              return execute();
 +
        if (detach) {
                daemonize();
                loginfo("Ready to rumble");
        if (pid_file)
                store_pid(pid_file);
  
 -      return serve(&listen_addr, listen_port, pass, gid);
 +      /* prepare argv for serving-processes */
 +      cld_argv = xmalloc(sizeof (char *) * (argc + 2));
 +      for (i = 0; i < argc; ++i)
 +              cld_argv[i] = argv[i];
 +      cld_argv[argc] = "--serve";
 +      cld_argv[argc+1] = NULL;
 +
 +      return serve(&listen_addr, listen_port, cred);
  }
diff --combined git-compat-util.h
index d0a1e480b6445a6f5ba3680672c255ab44ca43f0,625b2e4f142fcd756f80c20fd22c03c15f1b9214..490f96974417b00cd98de046ab1d6853425c3335
  #include <assert.h>
  #include <regex.h>
  #include <utime.h>
 -#ifndef __MINGW32__
 -#include <sys/wait.h>
 +#include <syslog.h>
+ #ifndef NO_SYS_POLL_H
  #include <sys/poll.h>
+ #else
+ #include <poll.h>
+ #endif
 +#ifndef __MINGW32__
 +#include <sys/wait.h>
  #include <sys/socket.h>
  #include <sys/ioctl.h>
  #include <termios.h>
  #include <arpa/inet.h>
  #include <netdb.h>
  #include <pwd.h>
+ #ifndef NO_INTTYPES_H
  #include <inttypes.h>
+ #else
+ #include <stdint.h>
+ #endif
  #if defined(__CYGWIN__)
  #undef _XOPEN_SOURCE
  #include <grp.h>
@@@ -387,14 -394,6 +395,14 @@@ static inline void *gitmempcpy(void *de
  }
  #endif
  
 +#ifdef NO_INET_PTON
 +int inet_pton(int af, const char *src, void *dst);
 +#endif
 +
 +#ifdef NO_INET_NTOP
 +const char *inet_ntop(int af, const void *src, char *dst, size_t size);
 +#endif
 +
  extern void release_pack_memory(size_t, int);
  
  typedef void (*try_to_free_t)(size_t);