summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-01-16 23:46:27 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2011-01-16 23:46:27 (GMT)
commit45f0910929a803f3031f0707a29ab1099d70a01c (patch)
tree9be35e23e012691887681117c1d9430e9fd8b7f1
parent50f72bae93133d4e30dadaead8c858217395b225 (diff)
downloadipxrelay-45f0910929a803f3031f0707a29ab1099d70a01c.zip
ipxrelay-45f0910929a803f3031f0707a29ab1099d70a01c.tar.gz
ipxrelay-45f0910929a803f3031f0707a29ab1099d70a01c.tar.bz2
ipxrelay-45f0910929a803f3031f0707a29ab1099d70a01c.tar.xz
autoconf machinery mostly from tftp-hpa, for portability work
Import autoconf machinery and substitution library functions from tftp-hpa. This is part of making this portable, especially to Windows.
-rw-r--r--MCONFIG.in65
-rw-r--r--Makefile58
-rw-r--r--aclocal.m4280
-rwxr-xr-xautogen.sh2
-rw-r--r--configure.in153
-rwxr-xr-xinstall-sh251
-rw-r--r--ipxrelay.c24
-rw-r--r--lib/daemon.c36
-rw-r--r--lib/getaddrinfo.c121
-rw-r--r--lib/getopt.h23
-rw-r--r--lib/getopt_long.c150
-rw-r--r--lib/sysexits.h114
12 files changed, 1255 insertions, 22 deletions
diff --git a/MCONFIG.in b/MCONFIG.in
new file mode 100644
index 0000000..1d068b5
--- /dev/null
+++ b/MCONFIG.in
@@ -0,0 +1,65 @@
+## -*- makefile -*- ------------------------------------------------------
+##
+## Copyright 2001-2007 H. Peter Anvin - All Rights Reserved
+##
+## This program is free software available under the same license
+## as the "OpenBSD" operating system, distributed at
+## http://www.openbsd.org/.
+##
+## -----------------------------------------------------------------------
+
+##
+## MCONFIG.in
+##
+## Basic Makefile definitions
+##
+
+# Source and object root
+SRCROOT = @SRCROOT@
+OBJROOT = @OBJROOT@
+
+# Prefixes
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+# Directory for user binaries
+BINDIR = @bindir@
+
+# Man page tree
+MANDIR = @mandir@
+
+# System binaries
+SBINDIR = @sbindir@
+
+# Data root directory. The name of this variable is in effect fixed, because
+# it appears in the default value of other variables.
+datarootdir = @datarootdir@
+
+# Binary suffixes
+O = @OBJEXT@
+X = @EXEEXT@
+
+# Install into alternate root area, e.g. for package generation
+INSTALLROOT =
+
+# Link
+LN_S = @LN_S@
+
+# Install program
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# Compiler and compiler flags
+CC = @CC@
+CFLAGS = @CFLAGS@ -I$(SRCROOT)
+
+# Link flags
+LDFLAGS = @LDFLAGS@
+
+# Additional library we need to build
+LIBOBJS = $(addprefix lib/,@LIBOBJS@)
+
+# ar and ranlib (for making libraries)
+AR = ar cq
+RANLIB = @RANLIB@
diff --git a/Makefile b/Makefile
index a7d65f4..bfb1ad3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,64 @@
-CC = gcc
-CWARN = -W -Wall
-COPT = -g -O2
-CREQ =
-CFLAGS = $(CWARN) $(COPT) $(CREQ)
-LDFLAGS =
+SRCROOT = .
+-include MCONFIG
-.SUFFIXES: .c .o .S .s .i
+.SUFFIXES: .c .$(O) .S .s .i
-.c.o:
+.c.$(O):
$(CC) $(CFLAGS) -c -o $@ $<
.c.s:
$(CC) $(CFLAGS) -S -o $@ $<
.c.i:
$(CC) $(CFLAGS) -E -o $@ $<
-.S.o:
+.S.$(O):
$(CC) $(CFLAGS) -c -o $@ $<
.S.s:
$(CC) $(CFLAGS) -E -o $@ $<
all: ipxrelay
-ipxrelay: ipxrelay.o
+ipxrelay$(X): ipxrelay.$(O) $(LIBOBJS)
$(CC) $(LDFLAGS) -o $@ $^
clean:
- rm -f ipxrelay *.o
+ rm -f ipxrelay$(X) *.$(O)
-spotless: clean
+distclean: clean
rm -f *~ \#*
+ rm -f MCONFIG aconfig.h config.lib config.status config.log
+ rm -rf autom4te.cache
+
+spotless: distclean
+ rm -f configure aconfig.h.in
+
+#
+# Autoconf rules
+#
+autoconf: configure aconfig.h.in
+
+config: MCONFIG aconfig.h
+
+release:
+ $(MAKE) autoconf
+ $(MAKE) tftp.spec
+ $(MAKE) distclean
+
+MCONFIG: configure MCONFIG.in aconfig.h.in
+ if test -x config.status; then \
+ ./config.status --recheck && ./config.status ; \
+ else \
+ ./configure ; \
+ fi
+
+aconfig.h: MCONFIG
+ : Generated by side effect
+
+# Adding "configure" to the dependencies serializes this with running
+# autoconf, because there are apparently race conditions between
+# autoconf and autoheader.
+aconfig.h.in: configure.in configure aclocal.m4
+ rm -f aconfig.h.in aconfig.h
+ autoheader
+
+configure: configure.in aclocal.m4
+ rm -rf MCONFIG configure config.log aconfig.h *.cache
+ autoconf
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..c07702c
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,280 @@
+dnl -----------------------------------------------------------------------
+dnl
+dnl Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+dnl Bostom MA 02111-1307, USA; either version 2 of the License, or
+dnl (at your option) any later version; incorporated herein by reference.
+dnl
+dnl -----------------------------------------------------------------------
+
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_CFLAGS()
+dnl
+dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation
+dnl --------------------------------------------------------------------------
+AC_DEFUN(PA_ADD_CFLAGS,
+[AC_MSG_CHECKING([if $CC accepts $1])
+ pa_add_cflags__old_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_TRY_LINK([#include <stdio.h>],
+ [printf("Hello, World!\n");],
+ AC_MSG_RESULT([yes]),
+ AC_MSG_RESULT([no])
+ CFLAGS="$pa_add_cflags__old_cflags")])
+
+dnl --------------------------------------------------------------------------
+dnl PA_SIGSETJMP
+dnl
+dnl Do we have sigsetjmp/siglongjmp? (AC_CHECK_FUNCS doesn't seem to work
+dnl for these particular functions.)
+dnl --------------------------------------------------------------------------
+AC_DEFUN(PA_SIGSETJMP,
+[AC_MSG_CHECKING([for sigsetjmp])
+ AC_TRY_LINK([
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif],
+ [sigjmp_buf buf;
+ sigsetjmp(buf,1);
+ siglongjmp(buf,2);],
+ AC_MSG_RESULT([yes])
+ $1,
+ AC_MSG_RESULT([no])
+ $2)])
+
+dnl --------------------------------------------------------------------------
+dnl PA_MSGHDR_MSG_CONTROL
+dnl
+dnl Does struct msghdr have the msg_control field?
+dnl --------------------------------------------------------------------------
+AH_TEMPLATE([HAVE_MSGHDR_MSG_CONTROL],
+[Define if struct msghdr has the msg_control field.])
+
+AC_DEFUN(PA_MSGHDR_MSG_CONTROL,
+ [AC_CHECK_MEMBER(struct msghdr.msg_control,
+ [AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL)],
+ [],
+ [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+ ])])
+
+dnl ------------------------------------------------------------------------
+dnl PA_STRUCT_IN_PKTINFO
+dnl
+dnl Look for definition of struct in_pktinfo, which at least has an
+dnl ipi_addr member. Some versions of glibc lack struct in_pktinfo;
+dnl if so we need to include the definition ourselves -- but we only
+dnl want to do that if absolutely necessary!
+dnl ------------------------------------------------------------------------
+AH_TEMPLATE([HAVE_STRUCT_IN_PKTINFO],
+[Define if struct in_pktinfo is defined.])
+
+AC_DEFUN(PA_STRUCT_IN_PKTINFO,
+ [AC_CHECK_MEMBER(struct in_pktinfo.ipi_addr,
+ [AC_DEFINE(HAVE_STRUCT_IN_PKTINFO)],
+ [],
+ [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+ ])])
+
+
+dnl ------------------------------------------------------------------------
+dnl PA_STRUCT_SOCKADDR_IN6
+dnl
+dnl Look for definition of struct sockaddr_in6, which at least has an
+dnl sin6_addr member
+dnl
+AH_TEMPLATE([HAVE_STRUCT_SOCKADDR_IN6],
+[Define if struct sockaddr_in6 is defined.])
+
+AC_DEFUN(PA_STRUCT_SOCKADDR_IN6,
+ [AC_CHECK_MEMBER(struct sockaddr_in6.sin6_addr,
+ [
+ AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6)
+ HAVE_INET6=true;
+ ],
+ [
+ HAVE_INET6=false;
+ ],
+ [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+ ])])
+
+dnl ------------------------------------------------------------------------
+dnl PA_STRUCT_ADDRINFO
+dnl
+dnl Look for definition of struct addrinfo, which at least has an
+dnl ai_addr member
+dnl
+AH_TEMPLATE([HAVE_STRUCT_ADDRINFO],
+[Define if struct addrinfo is defined.])
+
+AC_DEFUN(PA_STRUCT_ADDRINFO,
+ [AC_CHECK_MEMBER(struct addrinfo.ai_addr,
+ [AC_DEFINE(HAVE_STRUCT_ADDRINFO)],
+ [],
+ [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+ ])])
+
+dnl ------------------------------------------------------------------------
+dnl PA_STRUCT_IN6_PKTINFO
+dnl
+dnl Look for definition of struct in6_pktinfo, which at least has an
+dnl ipi6_addr member
+dnl
+AH_TEMPLATE([HAVE_STRUCT_IN6_PKTINFO],
+[Define if struct in6_pktinfo is defined.])
+
+AC_DEFUN(PA_STRUCT_IN6_PKTINFO,
+ [AC_CHECK_MEMBER(struct in6_pktinfo.ipi6_addr,
+ [AC_DEFINE(HAVE_STRUCT_IN6_PKTINFO)],
+ [],
+ [
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+ ])])
+
+dnl --------------------------------------------------------------------------
+dnl PA_HAVE_TCPWRAPPERS
+dnl
+dnl Do we have the tcpwrappers -lwrap? This can't be done using AC_CHECK_LIBS
+dnl due to the need to provide "allow_severity" and "deny_severity" variables
+dnl --------------------------------------------------------------------------
+AH_TEMPLATE([HAVE_TCPWRAPPERS],
+[Define if we have tcpwrappers (-lwrap) and <tcpd.h>.])
+
+AC_DEFUN(PA_HAVE_TCPWRAPPERS,
+[AC_CHECK_LIB([wrap], [main])
+ AC_MSG_CHECKING([for tcpwrappers])
+ AC_TRY_LINK(
+[
+#include <tcpd.h>
+int allow_severity = 0;
+int deny_severity = 0;
+],
+[
+ hosts_ctl("sample_daemon", STRING_UNKNOWN, STRING_UNKNOWN, STRING_UNKNOWN);
+],
+[
+ AC_DEFINE(HAVE_TCPWRAPPERS)
+ AC_MSG_RESULT([yes])
+],
+[
+ AC_MSG_RESULT([no])
+])])
+
+dnl ------------------------------------------------------------------------
+dnl PA_CHECK_INTTYPES_H_SANE
+dnl
+dnl At least some versions of AIX 4 have <inttypes.h> macros which are
+dnl completely broken. Try to detect those.
+dnl --------------------------------------------------------------------------
+AH_TEMPLATE([INTTYPES_H_IS_SANE],
+[Define if the macros in <inttypes.h> are usable])
+
+AC_DEFUN(PA_CHECK_INTTYPES_H_SANE,
+[AC_CHECK_HEADERS(inttypes.h,
+ [
+ AC_MSG_CHECKING([if inttypes.h is sane])
+ AC_TRY_LINK(
+ [
+#include <inttypes.h>
+#include <stdio.h>
+ ],
+ [uintmax_t max = UINTMAX_C(0);
+ printf("%"PRIuMAX"\n", max);],
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(INTTYPES_H_IS_SANE),
+ AC_MSG_RESULT([no (AIX, eh?)]))
+ ])
+])
+
+dnl ------------------------------------------------------------------------
+dnl PA_WITH_BOOL
+dnl
+dnl PA_WITH_BOOL(option, default, help, enable, disable)
+dnl
+dnl Provides a more convenient way to specify --with-option and
+dnl --without-option, with a default. default should be either 0 or 1.
+dnl ------------------------------------------------------------------------
+AC_DEFUN(PA_WITH_BOOL,
+[AC_ARG_WITH([$1], [$3],
+if test ["$withval"] != no; then
+[$4]
+else
+[$5]
+fi,
+if test [$2] -ne 0; then
+[$4]
+else
+[$5]
+fi)])
+
+dnl --------------------------------------------------------------------------
+dnl PA_HEADER_DEFINES
+dnl
+dnl PA_HEADER_DEFINES(header, type, value)
+dnl --------------------------------------------------------------------------
+AC_DEFUN(PA_HEADER_DEFINES,
+[AC_MSG_CHECKING([if $1 defines $3])
+ AH_TEMPLATE([HAVE_$3_DEFINITION], [Define if $1 defines $3])
+ AC_TRY_COMPILE([
+#include <$1>
+],
+[
+int main()
+{
+ $2 dummy = $3;
+ return 0;
+}
+],
+[
+ pa_header_define=`echo HAVE_$3_DEFINITION | tr '[a-z]' '[A-Z]'`
+ AC_DEFINE_UNQUOTED($pa_header_define)
+ AC_MSG_RESULT(yes)
+],
+[
+ AC_MSG_RESULT(no)
+])])
+
+dnl --------------------------------------------------------------------------
+dnl PA_SEARCH_LIBS_AND_ADD
+dnl
+dnl PA_SEARCH_LIBS_AND_ADD(function, libraries [,function to add])
+dnl --------------------------------------------------------------------------
+
+AC_DEFUN(PA_SEARCH_LIBS_AND_ADD,
+ [
+ AH_TEMPLATE(AS_TR_CPP(HAVE_$1), [Define if $1 function was found])
+ AC_SEARCH_LIBS($1, $2,
+ [
+ AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1))
+ pa_add_$1=false;
+ ],
+ [
+ XTRA=true;
+ if test $# -eq 3; then
+ AC_LIBOBJ($3)
+ else
+ AC_LIBOBJ($1)
+ fi
+ pa_add_$1=true;
+ ])])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..728a381
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+make autoconf
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..0931b5a
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,153 @@
+dnl
+dnl autoconf input file to generate MCONFIG
+dnl
+
+AC_PREREQ(2.61)
+AC_INIT(MCONFIG.in)
+AC_PREFIX_DEFAULT(/usr)
+
+AC_USE_SYSTEM_EXTENSIONS
+AC_ISC_POSIX
+AC_PROG_CC
+
+AC_C_CONST
+AC_C_INLINE
+
+PA_ADD_CFLAGS(-O3)
+PA_ADD_CFLAGS(-W)
+PA_ADD_CFLAGS(-Wall)
+PA_ADD_CFLAGS(-Wpointer-arith)
+PA_ADD_CFLAGS(-Wbad-function-cast)
+PA_ADD_CFLAGS(-Wcast-equal)
+PA_ADD_CFLAGS(-Wstrict-prototypes)
+PA_ADD_CFLAGS(-Wmissing-prototypes)
+PA_ADD_CFLAGS(-Wmissing-declarations)
+PA_ADD_CFLAGS(-Wnested-externs)
+PA_ADD_CFLAGS(-Winline)
+PA_ADD_CFLAGS(-Wwrite-strings)
+PA_ADD_CFLAGS(-Wundef)
+PA_ADD_CFLAGS(-Wshadow)
+PA_ADD_CFLAGS(-Wsign-compare)
+PA_ADD_CFLAGS(-pipe)
+PA_ADD_CFLAGS(-fno-strict-aliasing)
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(inttypes.h)
+AC_CHECK_HEADERS(stdint.h)
+AC_CHECK_HEADERS(stdbool.h)
+PA_CHECK_INTTYPES_H_SANE
+AC_CHECK_HEADERS(fcntl.h)
+AC_CHECK_HEADERS(stddef.h)
+AC_CHECK_HEADERS(stdlib.h)
+AC_CHECK_HEADERS(string.h)
+AC_CHECK_HEADERS(sysexits.h)
+AC_CHECK_HEADERS(time.h)
+AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(sys/stat.h)
+AC_CHECK_HEADERS(sys/time.h)
+AC_CHECK_HEADERS(sys/types.h)
+AC_CHECK_HEADERS(arpa/inet.h)
+AC_CHECK_HEADERS(netdb.h)
+AC_HEADER_TIME
+dnl This is needed on some versions of FreeBSD...
+AC_CHECK_HEADERS(machine/param.h)
+AC_CHECK_HEADERS(sys/socket.h)
+AC_CHECK_HEADERS(winsock2.h)
+AC_CHECK_HEADERS(winsock.h)
+
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_MODE_T
+AC_TYPE_SIZE_T
+AC_CHECK_TYPES(uint16_t)
+AC_CHECK_TYPES(uint32_t)
+AC_CHECK_TYPES(u_short)
+AC_CHECK_TYPES(u_long)
+
+dnl
+dnl <sys/socket.h> isn't among the list of standard headers that
+dnl autoconf checks, but POSIX requires <sys/socket.h> for socklen_t
+dnl to be defined.
+dnl
+AC_CHECK_TYPES(socklen_t,,,
+[
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+])
+
+AC_SEARCH_LIBS(socket, [socket ws2_32 wsock32], ,
+ [AC_MSG_ERROR(socket library not found)])
+
+AC_CHECK_FUNCS(fcntl)
+AC_CHECK_FUNCS(setsid)
+AC_CHECK_FUNCS(recvmsg)
+
+PA_MSGHDR_MSG_CONTROL
+PA_STRUCT_IN_PKTINFO
+PA_STRUCT_ADDRINFO
+
+dnl
+dnl Get common paths
+dnl
+SRCROOT=`cd $srcdir && pwd`
+OBJROOT=`pwd`
+
+XTRA=false
+AC_CHECK_LIB(cygwin, getopt_long)
+PA_SEARCH_LIBS_AND_ADD(getopt_long, [getopt cygwin iberty], getopt_long)
+PA_SEARCH_LIBS_AND_ADD(getaddrinfo, [nsl resolv])
+if $pa_add_getaddrinfo
+then
+ AC_SEARCH_LIBS(gethostbyname, [nsl resolv],
+ [AC_SEARCH_LIBS(herror, [nsl resolv], ,
+ [AC_MSG_ERROR(herror not found)])],
+ [AC_MSG_ERROR(gethostbyname not found)])
+else
+ AC_SEARCH_LIBS(freeaddrinfo, [nsl resolv], ,
+ [AC_MSG_ERROR(getaddrinfo but not freeaddrinfo found)])
+ AC_SEARCH_LIBS(gai_strerror, [nsl resolv], ,
+ [AC_MSG_ERROR(getaddrinfo but not gai_strerror found)])
+fi
+
+AC_CHECK_FUNCS(daemon)
+
+AC_SUBST(SRCROOT)
+AC_SUBST(OBJROOT)
+
+AC_CONFIG_HEADERS(aconfig.h)
+AC_OUTPUT(MCONFIG)
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..398a88e
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/ipxrelay.c b/ipxrelay.c
index 72eca97..adb4007 100644
--- a/ipxrelay.c
+++ b/ipxrelay.c
@@ -1,21 +1,25 @@
-#include <stdbool.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
-#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>
-#include <sysexits.h>
#include <inttypes.h>
#include <time.h>
+#ifdef __WIN32__
+#include "sysexits.h"
+#include <winsock2.h>
+#else
+#include <sysexits.h>
+#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
+#endif
#define VERSION_STRING "0.2"
@@ -52,13 +56,13 @@ struct opts {
const char *pidfile;
unsigned int port;
unsigned int timeout;
- bool foreground;
+ int foreground;
} opt = {
.address = NULL,
.pidfile = NULL,
.port = 231,
.timeout = 900,
- .foreground = false,
+ .foreground = 0,
};
@@ -76,11 +80,11 @@ struct ipx_addr {
uint16_t ip_port;
} __attribute__((packed));
-static inline bool is_ipx_null(const struct ipx_addr *addr)
+static int is_ipx_null(const struct ipx_addr *addr)
{
return addr->ip_addr == 0 && addr->ip_port == 0;
}
-static inline bool is_ipx_bcst(const struct ipx_addr *addr)
+static int is_ipx_bcst(const struct ipx_addr *addr)
{
return addr->ip_addr == 0xffffffff && addr->ip_port == 0xffff;
}
@@ -124,7 +128,7 @@ static void enable_timeout(int fd)
timeout.tv_sec = opt.timeout;
timeout.tv_usec = 0;
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof timeout);
}
static void disable_timeout(int fd)
@@ -134,7 +138,7 @@ static void disable_timeout(int fd)
timeout.tv_sec = 0;
timeout.tv_usec = 0;
- setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof timeout);
}
static void cleanup_timeouts(int fd, time_t now)
@@ -398,7 +402,7 @@ int main(int argc, char *argv[])
}
break;
case 'F':
- opt.foreground = true;
+ opt.foreground = 1;
break;
case 'P':
opt.pidfile = optarg;
diff --git a/lib/daemon.c b/lib/daemon.c
new file mode 100644
index 0000000..0eb39c9
--- /dev/null
+++ b/lib/daemon.c
@@ -0,0 +1,36 @@
+/*
+ * daemon.c - "daemonize" a process
+ */
+
+#include "config.h"
+
+int daemon(int nochdir, int noclose)
+{
+ int nullfd;
+ pid_t f;
+
+ if (!nochdir) {
+ if (chdir("/"))
+ return -1;
+ }
+
+ if (!noclose) {
+ if ((nullfd = open("/dev/null", O_RDWR)) < 0 ||
+ dup2(nullfd, 0) < 0 ||
+ dup2(nullfd, 1) < 0 || dup2(nullfd, 2) < 0)
+ return -1;
+ close(nullfd);
+ }
+
+ f = fork();
+ if (f < 0)
+ return -1;
+ else if (f > 0)
+ _exit(0);
+
+#ifdef HAVE_SETSID
+ return setsid();
+#else
+ return 0;
+#endif
+}
diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c
new file mode 100644
index 0000000..ef7c9ae
--- /dev/null
+++ b/lib/getaddrinfo.c
@@ -0,0 +1,121 @@
+/*
+ * getaddrinfo.c
+ *
+ * Simple version of getaddrinfo()
+ *
+ */
+
+#include "config.h"
+
+extern int errno;
+extern int h_errno;
+
+void freeaddrinfo(struct addrinfo *res)
+{
+ if (!res)
+ return;
+ if (res->ai_next)
+ freeaddrinfo(res->ai_next);
+ if (res->ai_addr)
+ free(res->ai_addr);
+ if (res->ai_canonname)
+ free(res->ai_canonname);
+ free(res);
+}
+
+int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ struct hostent *host;
+ struct sockaddr *sa;
+ int err, size = 0;
+
+ if ((!node) || (!res)) {
+ errno = EINVAL;
+ return EAI_SYSTEM;
+ }
+ *res = NULL;
+ /* we do not support service in this version */
+ if (service) {
+ errno = EINVAL;
+ return EAI_SYSTEM;
+ }
+ host = gethostbyname(node);
+ if (!host)
+ return EAI_NONAME;
+ if (hints) {
+ if (hints->ai_family != AF_UNSPEC) {
+ if (hints->ai_family != host->h_addrtype)
+ return EAI_ADDRFAMILY;
+ }
+ }
+ *res = malloc(sizeof(struct addrinfo));
+ if (!*res) {
+ return EAI_MEMORY;
+ }
+ memset(*res, 0, sizeof(struct addrinfo));
+ (*res)->ai_family = host->h_addrtype;
+ if (host->h_length) {
+ if (host->h_addrtype == AF_INET)
+ size = sizeof(struct sockaddr_in);
+#ifdef HAVE_IPV6
+ else if (host->h_addrtype == AF_INET6)
+ size = sizeof(struct sockaddr_in6);
+#endif
+ else {
+ free(*res);
+ *res = NULL;
+ return EAI_ADDRFAMILY;
+ }
+ sa = malloc(size);
+ if (!sa) {
+ free(*res);
+ *res = NULL;
+ return EAI_MEMORY;
+ }
+ memset(sa, 0, size);
+ (*res)->ai_addr = sa;
+ (*res)->ai_addrlen = size;
+ sa->sa_family = host->h_addrtype;
+ if (host->h_addrtype == AF_INET)
+ memcpy(&((struct sockaddr_in *)sa)->sin_addr, host->h_addr, host->h_length);
+#ifdef HAVE_IPV6
+ else
+ memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, host->h_addr, host->h_length);
+#endif
+ }
+ if (host->h_name)
+ (*res)->ai_canonname = strdup(host->h_name);
+
+ /* we only handle the first address entry and do not build a list now */
+ return 0;
+}
+
+
+
+const char *gai_strerror(int errcode)
+{
+ const char *s = NULL;
+
+ switch(errcode) {
+ case 0:
+ s = "no error";
+ break;
+ case EAI_MEMORY:
+ s = "no memory";
+ break;
+ case EAI_SYSTEM:
+ s = strerror(errno);
+ break;
+ case EAI_NONAME:
+ s = hstrerror(h_errno);
+ break;
+ case EAI_ADDRFAMILY:
+ s = "address does not match address family";
+ break;
+ default:
+ s = "unknown error code";
+ break;
+ }
+ return s;
+}
diff --git a/lib/getopt.h b/lib/getopt.h
new file mode 100644
index 0000000..c1ad561
--- /dev/null
+++ b/lib/getopt.h
@@ -0,0 +1,23 @@
+#ifndef LIB_GETOPT_H
+#define LIB_GETOPT_H
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+enum {
+ no_argument = 0,
+ required_argument = 1,
+ optional_argument = 2,
+};
+
+int getopt_long(int, char *const *, const char *,
+ const struct option *, int *);
+
+#endif /* LIB_GETOPT_H */
diff --git a/lib/getopt_long.c b/lib/getopt_long.c
new file mode 100644
index 0000000..49d1274
--- /dev/null
+++ b/lib/getopt_long.c
@@ -0,0 +1,150 @@
+/*
+ * getopt_long.c
+ *
+ * getopt_long(), or at least a common subset thereof:
+ *
+ * - Option reordering is not supported
+ * - -W foo is not supported
+ * - First optstring character "-" not supported.
+ */
+
+#include "config.h"
+
+char *optarg;
+int optind, opterr, optopt;
+
+static struct getopt_private_state {
+ const char *optptr;
+ const char *last_optstring;
+ char *const *last_argv;
+} pvt;
+
+static inline const char *option_matches(const char *arg_str,
+ const char *opt_name)
+{
+ while (*arg_str != '\0' && *arg_str != '=') {
+ if (*arg_str++ != *opt_name++)
+ return NULL;
+ }
+
+ if (*opt_name)
+ return NULL;
+
+ return arg_str;
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring,
+ const struct option *longopts, int *longindex)
+{
+ const char *carg;
+ const char *osptr;
+ int opt;
+
+ /* getopt() relies on a number of different global state
+ variables, which can make this really confusing if there is
+ more than one use of getopt() in the same program. This
+ attempts to detect that situation by detecting if the
+ "optstring" or "argv" argument have changed since last time
+ we were called; if so, reinitialize the query state. */
+
+ if (optstring != pvt.last_optstring || argv != pvt.last_argv ||
+ optind < 1 || optind > argc) {
+ /* optind doesn't match the current query */
+ pvt.last_optstring = optstring;
+ pvt.last_argv = argv;
+ optind = 1;
+ pvt.optptr = NULL;
+ }
+
+ carg = argv[optind];
+
+ /* First, eliminate all non-option cases */
+
+ if (!carg || carg[0] != '-' || !carg[1])
+ return -1;
+
+ if (carg[1] == '-') {
+ const struct option *lo;
+ const char *opt_end = NULL;
+
+ optind++;
+
+ /* Either it's a long option, or it's -- */
+ if (!carg[2]) {
+ /* It's -- */
+ return -1;
+ }
+
+ for (lo = longopts; lo->name; lo++) {
+ if ((opt_end = option_matches(carg+2, lo->name)))
+ break;
+ }
+ if (!opt_end)
+ return '?';
+
+ if (longindex)
+ *longindex = lo-longopts;
+
+ if (*opt_end == '=') {
+ if (lo->has_arg)
+ optarg = (char *)opt_end+1;
+ else
+ return '?';
+ } else if (lo->has_arg == 1) {
+ if (!(optarg = argv[optind]))
+ return '?';
+ optind++;
+ }
+
+ if (lo->flag) {
+ *lo->flag = lo->val;
+ return 0;
+ } else {
+ return lo->val;
+ }
+ }
+
+ if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) {
+ /* Someone frobbed optind, change to new opt. */
+ pvt.optptr = carg + 1;
+ }
+
+ opt = *pvt.optptr++;
+
+ if (opt != ':' && (osptr = strchr(optstring, opt))) {
+ if (osptr[1] == ':') {
+ if (*pvt.optptr) {
+ /* Argument-taking option with attached
+ argument */
+ optarg = (char *)pvt.optptr;
+ optind++;
+ } else {
+ /* Argument-taking option with non-attached
+ argument */
+ if (argv[optind + 1]) {
+ optarg = (char *)argv[optind+1];
+ optind += 2;
+ } else {
+ /* Missing argument */
+ optind++;
+ return (optstring[0] == ':')
+ ? ':' : '?';
+ }
+ }
+ return opt;
+ } else {
+ /* Non-argument-taking option */
+ /* pvt.optptr will remember the exact position to
+ resume at */
+ if (!*pvt.optptr)
+ optind++;
+ return opt;
+ }
+ } else {
+ /* Unknown option */
+ optopt = opt;
+ if (!*pvt.optptr)
+ optind++;
+ return '?';
+ }
+}
diff --git a/lib/sysexits.h b/lib/sysexits.h
new file mode 100644
index 0000000..37246b6
--- /dev/null
+++ b/lib/sysexits.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sysexits.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SYSEXITS_H
+#define _SYSEXITS_H 1
+
+/*
+ * SYSEXITS.H -- Exit status codes for system programs.
+ *
+ * This include file attempts to categorize possible error
+ * exit statuses for system programs, notably delivermail
+ * and the Berkeley network.
+ *
+ * Error numbers begin at EX__BASE to reduce the possibility of
+ * clashing with other exit statuses that random programs may
+ * already return. The meaning of the codes is approximately
+ * as follows:
+ *
+ * EX_USAGE -- The command was used incorrectly, e.g., with
+ * the wrong number of arguments, a bad flag, a bad
+ * syntax in a parameter, or whatever.
+ * EX_DATAERR -- The input data was incorrect in some way.
+ * This should only be used for user's data & not
+ * system files.
+ * EX_NOINPUT -- An input file (not a system file) did not
+ * exist or was not readable. This could also include
+ * errors like "No message" to a mailer (if it cared
+ * to catch it).
+ * EX_NOUSER -- The user specified did not exist. This might
+ * be used for mail addresses or remote logins.
+ * EX_NOHOST -- The host specified did not exist. This is used
+ * in mail addresses or network requests.
+ * EX_UNAVAILABLE -- A service is unavailable. This can occur
+ * if a support program or file does not exist. This
+ * can also be used as a catchall message when something
+ * you wanted to do doesn't work, but you don't know
+ * why.
+ * EX_SOFTWARE -- An internal software error has been detected.
+ * This should be limited to non-operating system related
+ * errors as possible.
+ * EX_OSERR -- An operating system error has been detected.
+ * This is intended to be used for such things as "cannot
+ * fork", "cannot create pipe", or the like. It includes
+ * things like getuid returning a user that does not
+ * exist in the passwd file.
+ * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
+ * etc.) does not exist, cannot be opened, or has some
+ * sort of error (e.g., syntax error).
+ * EX_CANTCREAT -- A (user specified) output file cannot be
+ * created.
+ * EX_IOERR -- An error occurred while doing I/O on some file.
+ * EX_TEMPFAIL -- temporary failure, indicating something that
+ * is not really an error. In sendmail, this means
+ * that a mailer (e.g.) could not create a connection,
+ * and the request should be reattempted later.
+ * EX_PROTOCOL -- the remote system returned something that
+ * was "not possible" during a protocol exchange.
+ * EX_NOPERM -- You did not have sufficient permission to
+ * perform the operation. This is not intended for
+ * file system problems, which should use NOINPUT or
+ * CANTCREAT, but rather for higher level permissions.
+ */
+
+#define EX_OK 0 /* successful termination */
+
+#define EX__BASE 64 /* base value for error messages */
+
+#define EX_USAGE 64 /* command line usage error */
+#define EX_DATAERR 65 /* data format error */
+#define EX_NOINPUT 66 /* cannot open input */
+#define EX_NOUSER 67 /* addressee unknown */
+#define EX_NOHOST 68 /* host name unknown */
+#define EX_UNAVAILABLE 69 /* service unavailable */
+#define EX_SOFTWARE 70 /* internal software error */
+#define EX_OSERR 71 /* system error (e.g., can't fork) */
+#define EX_OSFILE 72 /* critical OS file missing */
+#define EX_CANTCREAT 73 /* can't create (user) output file */
+#define EX_IOERR 74 /* input/output error */
+#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
+#define EX_PROTOCOL 76 /* remote error in protocol */
+#define EX_NOPERM 77 /* permission denied */
+#define EX_CONFIG 78 /* configuration error */
+
+#define EX__MAX 78 /* maximum listed value */
+
+#endif /* sysexits.h */