下载 pure-ftpd-1.0.47.tar.gz,解压后目录结构如下:
目录,每个目录中均包含一个Makefile.am
gui | |
m4 | |
Man | |
Pam | |
Puredb | Puredb的项目,src里包含了源代码 |
src | ftp服务器代码 |
根目录
NEWS README AUTHORS ChangeLog automake 工具要求要有的文件。
autoscan -->> configure.scan -->> configure.ac 编辑configure.ac文件
aclocal ->>> aclocal.m4 ,编辑aclocal文件
autoheader --> config.h.in
automake --add-missing -->> Makefile.am ->> Makefile.in
autoconf --> 利用M4解析configure.ac,生成shell脚本configure
./configure -->> Makefile config.h
调用autoheader,扫描configure.ac(configure.in)、acconfig.h(如果存在),生成config.h.in宏定义文件,里面主要是根据configure.ac中某些特定宏(如AC_DEFINE)生成的#define和#undefine宏,configure在将根据实际的探测结果决定这些宏是否定义(具体见后面例子)。
compile COPYING depcomp INSTALL install-sh missing 六个符号链接文件,为automake --add-missing时生成。
config.h.in autoheader时生成
configure autoconf时生成
pure-ftpd.conf.in 生成pure-ftpd.conf (configure.ac中定义的输出文件),并安装到etc目录下(Makefile.am中定义)
aclocal.m4,aclocal命令生成的文件,文件末尾增加
m4_include([m4/ax_check_compile_flag.m4])
m4_include([m4/ax_check_link_flag.m4])
m4_include([m4/getloadavg.m4])
将三个m4文件加入,使得configure.ac可以使用这三个文件定义的宏。
.in文件如何变成实际安装的文件?在configure.ac中定义输出文件(AC_CONFIG_FILES),在调用configure命令式生成。
Makefile.am:
打包时会包含的文件,主要是配置文件
EXTRA_DIST = THANKS \
HISTORY \
CONTACT \
FAQ \
Makefile.gui \
README.LDAP \
README.MySQL \
README.PGSQL \
README.Configuration-File \
README.Virtual-Users \
README.Authentication-Modules \
README.Windows \
README.TLS \
README.MacOS-X \
README.Donations \
pureftpd.schema \
pureftpd-ldap.conf \
pureftpd-mysql.conf \
pureftpd-pgsql.conf \
pure-ftpd.png
项目包含6个子目录,每个子目录都会有Makefile.am
SUBDIRS= puredb \
src \
man \
pam \
gui \
m4
sbin_PROGRAMS, lib_LIBRARIES指生成库, sysconf_DATA指系统配置文件, man_MANS指手册等。相应的,在make install时会把他们拷贝到对应的目录。例如,指定man_MANS=hello.man.3则会把该文件安装到prefix/man目录下,指定sysconf_DATA=hello.conf就会把配置文件放到prefix/etc目录下。
目前只有pure-ftpd.conf.in文件,编译时会变成pure-ftpd.conf,安装时会安装到 /etc目录下。
sysconf_DATA= pure-ftpd.conf
GUI目录
只有build.sh, 一个基于GUI编译的脚本。
Makefile.am:将脚本包含到打包文件中。
EXTRA_DIST = \
build.sh
M4目录
含3个M4文件,和一个Makefile.am文件。
getloadavg.m4 提供宏定义: AC_FUNC_GETLOADAVG
ax_check_compile_flag.m4 提供宏定义:AX_CHECK_COMPILE_FLAG
ax_check_link_flag.m4 提供宏定义:AX_CHECK_LINK_FLAG
这3个宏定义在configure.ac中用到。
Makefile.am: :将脚本getloadavg.m4包含到打包文件中。
EXTRA_DIST = \
getloadavg.m4
Man目录
含9个.8的帮助文件,目前是.in文件,在configure时会生成去掉.in后缀的文件(在configure.ac 中定义)。和Makefile.am
安装到man目录的8目录下。
man_MANS = \
pure-ftpd.8 \
pure-ftpwho.8 \
pure-mrtginfo.8 \
pure-uploadscript.8 \
pure-statsdecode.8 \
pure-quotacheck.8 \
pure-pw.8 \
pure-pwconvert.8 \
pure-authd.8
这个不知道什么意思
CLEANFILES = \
pure-ftpd.8 \
pure-ftpwho.8 \
pure-mrtginfo.8 \
pure-uploadscript.8 \
pure-statsdecode.8 \
pure-quotacheck.8 \
pure-pw.8 \
pure-pwconvert.8 \
pure-authd.8
pam目录
README
pure-ftpd PAM配置文件,拷贝到/etc/pam.d目录下
ftpusers 不允许登陆ftp的用户列表,拷贝到/etc目录下
Makefile.am
将三个文件打包
EXTRA_DIST = \
ftpusers \
pure-ftpd \
README
puredb目录
README.FIRST README
Makefile.am:
SUBDIRS = \
src
EXTRA_DIST = \
README.FIRST
src子目录
Makefile.am
noinst_LIBRARIES = libpuredb_read.a libpuredb_write.a
noinst_HEADERS = puredb_read.h puredb_write.h
noinst_PROGRAMS = example_read example_write regression
libpuredb_read_a_SOURCES = puredb_read.c puredb_read.h puredb_p.h
libpuredb_write_a_SOURCES = puredb_write.c puredb_write.h puredb_p.h
example_read_LDADD = libpuredb_read.a
example_write_LDADD = libpuredb_write.a
regression_LDADD = libpuredb_read.a libpuredb_write.a
example_read_SOURCES = example_read.c puredb_read.h
example_write_SOURCES = example_write.c puredb_write.h
regression_SOURCES = regression.c puredb_read.h puredb_write.h puredb_p.h
src目录
configure.ac
autoscan 生成的configure.scan:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_MAKE_SET
# Checks for libraries.
# Checks for header files.
AC_FUNC_ALLOCA
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h locale.h memory.h netdb.h netinet/in.h nlist.h sgtty.h shadow.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/mount.h sys/param.h sys/socket.h sys/statvfs.h sys/time.h sys/vfs.h syslog.h termio.h termios.h unistd.h utime.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_C_INLINE
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT32_T
# Checks for library functions.
AC_FUNC_CHOWN
AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK
AC_FUNC_GETGROUPS
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_FUNC_MMAP
AC_FUNC_REALLOC
AC_FUNC_STRTOD
AC_FUNC_WAIT3
AC_CHECK_FUNCS([alarm dup2 endpwent ftruncate getcwd gethostbyaddr gethostbyname gethostname getpagesize getspnam gettimeofday getusershell inet_ntoa memmove memset mkdir mkfifo munmap putenv realpath rmdir select setlocale socket strcasecmp strchr strdup strerror strncasecmp strpbrk strrchr strspn strstr strtol strtoul strtoull tzset utime])
AC_CONFIG_FILES([Makefile
gui/Makefile
m4/Makefile
man/Makefile
pam/Makefile
puredb/Makefile
puredb/src/Makefile
src/Makefile])
AC_OUTPUT
修改如下:
AC_INIT([pure-ftpd], [1.0.47], [bugs at pureftpd dot org])
AC_CONFIG_SRCDIR([src/ftpd.c])
初始化automake宏
AM_INIT_AUTOMAKE([1.9 dist-bzip2 tar-ustar])
AC_CONFIG_LIBOBJ_DIR(src) 还不太清楚
AC_SUBST(VERSION)
ISODATE=`date +%Y-%m-%d`
AC_SUBST(ISODATE)
Makefiles中的替换
发布版本中每个包含了需要被编译或者被安装的文件的目录都应该含有一个文件`Makefile.in', configure将利用它在那个目录中创建一个`Makefile'。 为了创建`Makefile',configure进行一个简单的变量替换:用configure为`@variable@'选取的值,在`Makefile.in'中对它们进行替换。 按照这种方式被替换到输出文件中的变量被称为输出变量。在configure中,它们是普通 的shell变量。为了让configure把特殊的变量替换到输出文件中,必须把那个变量的名字作为调用 AC_SUBST的参数。其他变量的任何`@variable@'都保持不变。关于 使用AC_SUBST创建输出变量的详情,请参见设定输出变量。
使用configure脚本的软件应该发布文件`Makefile.in',而不是`Makefile'; 这样,用户就可以在编译它之前正确地为本地系统进行配置了。
关于应该把哪些东西放入`Makefile'的详情,请参见GNU编码标准中的`Makefile惯例'。
在Makefile.in中
ISODATE = @ISODATE@
Makefile中
ISODATE = 2018-10-20
AC_PROG_RANLIB 用于生成静态库
LX_CFLAGS=${CFLAGS-NONE}
AM_PROG_CC_C_O
AC_USE_SYSTEM_EXTENSIONS
AC_SEARCH_LIBS([strerror],[cposix])
检测编译和链接选项:
AX_CHECK_COMPILE_FLAG([-fPIC], [
AX_CHECK_LINK_FLAG([-fPIC],
[CFLAGS="$CFLAGS -fPIC"]
)
])
AS_IF([test "$enable_pie" != "no"],[
AX_CHECK_COMPILE_FLAG([-fPIE], [
AX_CHECK_LINK_FLAG([-pie], [
[CFLAGS="$CFLAGS -fPIE"
LDFLAGS="$LDFLAGS -pie"]
])
])
])
AX_CHECK_COMPILE_FLAG([-fwrapv], [CFLAGS="$CFLAGS -fwrapv"])
AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-aliasing"])
AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CFLAGS="$CFLAGS -fno-strict-overflow"])
AS_IF([echo `(uname -s) 2>/dev/null` | $GREP "CYGWIN" > /dev/null], [
AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"])
], [
AS_IF([test `(uname -s) 2>/dev/null` = "DragonFly"],
[
AX_CHECK_COMPILE_FLAG([-fstack-protector], [
AX_CHECK_LINK_FLAG([-fstack-protector],
[CFLAGS="$CFLAGS -fstack-protector"]
)
])
],
[
AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [
AX_CHECK_LINK_FLAG([-fstack-protector-all],
[CFLAGS="$CFLAGS -fstack-protector-all"]
)
])
]
)
])
AX_CHECK_COMPILE_FLAG([-Winit-self], [CFLAGS="$CFLAGS -Winit-self"])
AX_CHECK_COMPILE_FLAG([-Wwrite-strings], [CFLAGS="$CFLAGS -Wwrite-strings"])
AX_CHECK_COMPILE_FLAG([-Wdiv-by-zero], [CFLAGS="$CFLAGS -Wdiv-by-zero"])
AC_ARG_VAR([CWFLAGS], [define to compilation flags for generating extra warnings]) 定义一个变量 CWFLAGS,输出到Makefile中。
AX_CHECK_COMPILE_FLAG([-Wall], [CWFLAGS="$CWFLAGS -Wall"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wextra], [CWFLAGS="$CWFLAGS -Wextra"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wbad-function-cast], [CWFLAGS="$CWFLAGS -Wbad-function-cast"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wcast-align], [CWFLAGS="$CWFLAGS -Wcast-align"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wcast-qual], [CWFLAGS="$CWFLAGS -Wcast-qual"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wchar-subscripts], [CWFLAGS="$CWFLAGS -Wchar-subscripts"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wcomment], [CWFLAGS="$CWFLAGS -Wcomment"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wfloat-equal], [CWFLAGS="$CWFLAGS -Wfloat-equal"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wformat=2], [CWFLAGS="$CWFLAGS -Wformat=2"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wimplicit], [CWFLAGS="$CWFLAGS -Wimplicit"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-declarations], [CWFLAGS="$CWFLAGS -Wmissing-declarations"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-prototypes], [CWFLAGS="$CWFLAGS -Wmissing-prototypes"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnormalized=id], [CWFLAGS="$CWFLAGS -Wnormalized=id"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Woverride-init], [CWFLAGS="$CWFLAGS -Woverride-init"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wparentheses], [CWFLAGS="$CWFLAGS -Wparentheses"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wpointer-arith], [CWFLAGS="$CWFLAGS -Wpointer-arith"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wredundant-decls], [CWFLAGS="$CWFLAGS -Wredundant-decls"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wstrict-prototypes], [CWFLAGS="$CWFLAGS -Wstrict-prototypes"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wswitch-enum], [CWFLAGS="$CWFLAGS -Wswitch-enum"])
AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wvariable-decl], [CWFLAGS="$CWFLAGS -Wvariable-decl"])
AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"])
AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"])
AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"])
添加include目录和lib目录。
if test -d /usr/local/include; then
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
fi
if test -d /usr/kerberos/include; then
CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
fi
if test -d /usr/local/lib; then
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
添加一个定义
CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"
检查头文件:
AC_SYS_LARGEFILE (checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
)
AC_HEADER_STDC
AC_HEADER_STAT
AC_HEADER_TIME
AC_HEADER_DIRENT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/param.h ioctl.h sys/ioctl.h)
AC_CHECK_HEADERS(sys/vfs.h sys/statvfs.h sys/sendfile.h sys/uio.h)
AC_CHECK_HEADERS(sys/time.h sys/resource.h sys/capability.h)
AC_CHECK_HEADERS(shadow.h getopt.h stddef.h stdint.h)
AC_CHECK_HEADERS(netinet/in_systm.h netinet/in.h sys/pstat.h sys/file.h)
AC_CHECK_HEADERS(sys/mount.h, [], [],
[#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif])
AC_CHECK_HEADERS(fcntl.h sys/fcntl.h sys/loadavg.h sys/ptrace.h)
AC_CHECK_HEADERS(security/pam_appl.h security/pam_misc.h)
AC_CHECK_HEADERS(security/pam_modules.h security/pam_filter.h)
AC_CHECK_HEADERS(pam/pam_appl.h pam/pam_misc.h pam/pam_modules.h)
AC_CHECK_HEADERS(pam/pam_filter.h)
AC_CHECK_HEADERS(sgtty.h termio.h)
AC_CHECK_HEADERS(locale.h)
AC_CHECK_HEADERS(stdarg.h varargs.h)
AC_CHECK_HEADERS(windows.h io.h)
AC_CHECK_HEADERS(crypt.h)
AC_CHECK_HEADERS(utime.h)
AC_CHECK_HEADERS(openssl/ssl.h openssl/ec.h)
AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h)
AC_CHECK_HEADERS(iconv.h)
AC_SYS_POSIX_TERMIOS
如果checking POSIX termios... yes 则定义HAVE_POSIX_TERMIOS
if test "x$ac_cv_sys_posix_termios" = "xyes"; then
AC_DEFINE(HAVE_POSIX_TERMIOS,,[Define if you have POSIX termios(描述)])
fi
检查类型的大小
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(mode_t)
检查字节序
AC_C_BIGENDIAN
检查数据类型
AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UID_T
AC_TYPE_PID_T
AC_TYPE_OFF_T
AC_TYPE_MODE_T
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
AC_CHECK_MEMBER(struct tm.tm_gmtoff, [AC_DEFINE(STRUCT_TM_TM_GMTOFF,,[Define if you have struct tm/tm_gmtoff])],,[
#include <sys/types.h>
#include <$ac_cv_struct_tm>
])
输出configuire脚本的提示
AC_MSG_CHECKING([whether timezone is scalar])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <$ac_cv_struct_tm>
]], [[timezone = 42L]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SCALAR_TIMEZONE,,[Define if your timezone is a scalar number])
],[ AC_MSG_RESULT(no) ])
AC_CHECK_TYPE(nlink_t, , [AC_DEFINE(nlink_t, int, [nlink_t type])],
[
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
])
检查函数
dnl Socket things
AC_CHECK_FUNC(connect, , [AC_CHECK_LIB(socket, connect)])
AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(resolv, gethostbyname)])
AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname)])
if test "x$ac_cv_lib_nsl_gethostbyname" != "xyes" && test "x$ac_cv_func_gethostbyname" != "xyes" ; then
AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(socket, gethostbyname)])
fi
if test "$ac_cv_lib_nsl_gethostbyname" = "$ac_cv_func_gethostbyname" ; then
AC_MSG_CHECKING([if we can include libnsl + libsocket])
LIBS="-lnsl -lsocket $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[(void) gethostbyname]])],[my_ac_link_result=yes],[my_ac_link_result=no ])
if test "$my_ac_link_result" = "no" ; then
AC_MSG_RESULT([failure])
AC_MSG_ERROR([unable to use gethostbyname()])
else
AC_MSG_RESULT([success])
fi
fi
dnl Compiler characteristics
AC_PROG_GCC_TRADITIONAL
AC_C_CONST
AC_C_INLINE
dnl Options
AM_WITH_DMALLOC
AC_ARG_ENABLE(pie,
[AS_HELP_STRING(--enable-pie,Produce position independent executables @<:@default=yes@:>@)],
enable_pie=$enableval, enable_pie="maybe")
AC_ARG_ENABLE(ssp,
[AS_HELP_STRING(--disable-ssp,Don't compile with -fstack-protector)],
[AS_IF([test "x$enableval" = "xno"], [
nxflags=""
for flag in `echo $CFLAGS`; do
case "$flag" in
-fstack-protector*) ;;
*) AS_VAR_APPEND([nxflags], [" $flag"]) ;;
esac
done
CFLAGS="$nxflags"
])
])
AC_ARG_WITH
AC_ARG_WITH(common,"--with-common prefix for installed COMMON-LIBRARY",COMMON_LIBRARY_HOME=$withval,COMMON_LIBRARY_HOME=)
AC_SUBST(COMMON_LIBRARY_HOME)
AS_IF([test "x$COMMON_LIBRARY_HOME" = "x"],[AC_MSG_ERROR([*** COMMON-LIBRARY could not be located. Please use the --with-common option ***.])])
经过上面的操作后,在Makefile.am中就可以引用common-library_home了,后面的AS_IF表示如果没有指定,则报错退出(执行configure时)。
最好将AC_ARG_WITH最好修改成:
1. AC_ARG_WITH(common, AS_HELP_STRING([--with-common], [prefix for installed COMMON-LIBRARY]),COMMON_LIBRARY_HOME=$withval,COMMON_LIBRARY_HOME=)
AC_ARG_WITH(standalone,
[AS_HELP_STRING(--without-standalone,Don't compile the standalone server code)],
[ if test "x$withval" = "xno" ; then
AC_DEFINE(NO_STANDALONE,,[without standalone])
no_standalone=yes
fi ])
if test "x$no_standalone" = "xyes" && test "x$no_inetd" = "xyes" ; then
AC_MSG_ERROR(You can't disable both standalone and inetd mode.)
fi
AC_MSG_WARN(shadow.h was found, but getspnam() isn't available)
AC_ARG_WITH(pam,
[AS_HELP_STRING(--with-pam,Enable PAM support (default=disabled))],
[ if test "x$withval" = "xyes" ; then
with_pam="yes"
fi ])
AC_MSG_CHECKING([whether __ss_len is defined])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
]], [[
do {
struct sockaddr_storage a;
(void) a.__ss_len;
} while(0)
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE___SS_LEN,,[define if you have __ss_len])
],[
AC_MSG_RESULT(no)
])
AC_ARG_WITH(everything,
[AS_HELP_STRING(--with-everything,Build a big server with almost everything)],
[ if test "x$withval" = "xyes" ; then
AC_DEFINE(WITH_ALTLOG)
AC_DEFINE(COOKIE)
AC_DEFINE(THROTTLING)
AC_DEFINE(RATIOS)
AC_DEFINE(QUOTAS)
AC_DEFINE(WITH_UPLOAD_SCRIPT)
AC_DEFINE(WITH_VIRTUAL_HOSTS)
AC_DEFINE(WITH_PUREDB)
AC_DEFINE(WITH_EXTAUTH)
AC_DEFINE(FTPWHO)
AC_DEFINE(WITH_DIRALIASES)
AC_DEFINE(PER_USER_LIMITS)
with_bonjour='yes'
fi ])
AC_CHECK_LIB(crypt, crypt, , )
AC_CHECK_LIB(sodium, crypto_pwhash_scryptsalsa208sha256_str)
# Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_MMAP
AC_FUNC_MEMCMP
AC_FUNC_STRFTIME
AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_FUNC_GETLOADAVG(src)
AC_FUNC_GETGROUPS
AC_FUNC_WAIT3
AC_FUNC_UTIME_NULL
AC_FUNC_STRTOD
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_MKTIME
AC_FUNC_LSTAT
AC_FUNC_FORK
AC_FUNC_ERROR_AT_LINE
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_CHOWN
AC_C_VOLATILE
AC_CHECK_FUNCS(initgroups setrlimit waitpid setproctitle getopt_long)
AC_CHECK_FUNCS(seteuid setreuid setresuid setegid setregid setresgid)
AC_CHECK_FUNCS(statvfs statfs putenv setenv unsetenv getpagesize realpath)
AC_CHECK_FUNCS(pread posix_fadvise ptrace)
AC_CHECK_FUNCS(strtoull strtoq)
AC_CHECK_FUNCS(strlcpy strlcat)
AC_CHECK_FUNCS(memset munmap strdup fileno mapviewoffile madvise)
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_ntop inet_pton)
AC_CHECK_FUNCS(setusershell setgroups snprintf vsnprintf vfprintf gethostname)
AC_CHECK_FUNCS(setlocale timegm)
AC_CHECK_FUNCS(tzset utime utimes mknod mkfifo)
AC_CHECK_FUNCS(random srandomdev arc4random arc4random_stir arc4random_addrandom)
AC_CHECK_FUNCS(closefrom explicit_bzero getpwnam_shadow)
AC_MSG_CHECKING([whether statvfs64() is defined])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
]], [[
for (;;) {
struct statvfs64 a;
if (statvfs64(".", &a) == 0 || a.f_bsize != 0) {
break;
}
}
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_STATVFS64,,[define if you have statvfs64])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING(whether snprintf is C99 conformant)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
int main(void)
{
char buf[4];
(void) fprintf(fopen("conftestval", "w"), "%d\n",
(int) snprintf(buf, sizeof buf, "12345678"));
return 0;
}
]])],[CONF_SNPRINTF_TYPE=`cat conftestval`
],[],[CONF_SNPRINTF_TYPE=8])
AC_MSG_RESULT(done)
if test "x$CONF_SNPRINTF_TYPE" = "x" ; then
AC_MSG_WARN(your operating system doesn't implement snprintf)
else
AC_DEFINE_UNQUOTED(CONF_SNPRINTF_TYPE, $CONF_SNPRINTF_TYPE, [return value of an overflowed snprintf])
fi
AC_MSG_CHECKING(whether getgroups 0 is sane)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
int main(void)
{
return getgroups(0, NULL) <= 0;
}
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(SAFE_GETGROUPS_0,,[Define is getgroups(0, NULL) works on your system])
],[AC_MSG_RESULT(no)
],[AC_MSG_RESULT(suppose that it doesnt)])
AC_MSG_CHECKING(whether realpath likes unreadable directories)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifndef PATH_MAX
# define PATH_MAX MAXPATHLEN
#endif
int main(void)
{
char x[PATH_MAX];
if (mkdir("x", 0300) != 0) {
return 1;
}
if (mkdir("x/y", 0300) != 0) {
rmdir("x");
return 2;
}
if (chdir("x") != 0) {
rmdir("x/y");
rmdir("x");
return 3;
}
if (realpath("y", x) == NULL) {
rmdir("y");
rmdir("../x");
return 4;
}
rmdir("y");
rmdir("../x");
return 0;
}
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(REALPATH_WORKS_WITH_UNREADABLE_DIRECTORIES,,
[Define if realpath() works on unreadable directories])
],[AC_MSG_RESULT(no)
AC_DEFINE(USE_BUILTIN_REALPATH)
],[AC_MSG_RESULT(no)
AC_DEFINE(USE_BUILTIN_REALPATH)])
AC_MSG_CHECKING(whether you already have a standard MD5 implementation)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <md5.h>
int main(void)
{
MD5_CTX ctx;
char b[33];
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *) "test", 4U);
MD5End(&ctx, b);
b[32] = 0;
return strcasecmp(b, "098f6bcd4621d373cade4e832627b4f6");
}
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_SYSTEM_CRYPT_MD5,,[Define if you already have standard
MD5 functions])
],[AC_MSG_RESULT(no)
],[AC_MSG_RESULT(assuming no)])
AC_MSG_CHECKING(whether you already have a standard SHA1 implementation)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sha1.h>
int main(void)
{
SHA1_CTX ctx;
char b[41];
SHA1Init(&ctx);
SHA1Update(&ctx, (const unsigned char *) "test", 4U);
SHA1End(&ctx, b);
b[40] = 0;
return strcasecmp(b, "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3");
}
]])],[
AC_MSG_RESULT(yes)
AC_DEFINE(USE_SYSTEM_CRYPT_SHA1,,[Define if you already have standard
SHA1 functions])
],[AC_MSG_RESULT(no)
],[AC_MSG_RESULT(assuming no)])
AC_MSG_CHECKING([whether we are inside a Virtuozzo virtual host])
if test -d /proc/vz; then
AC_MSG_RESULT(yes)
AC_DEFINE(VIRTUOZZO,,[Define if you are inside a Virtuozzo virtual
host])
else
AC_MSG_RESULT(no)
fi
AC_MSG_CHECKING(default TCP send buffer size)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(void)
{
int fd,val=0,len=sizeof(int);
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) return 1;
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) < 0) return 1;
if (val <= 0) return 1;
fprintf (fopen("conftestval", "w"), "%d\n", val);
return 0;
}
]])],[CONF_TCP_SO_SNDBUF=`cat conftestval`],[CONF_TCP_SO_SNDBUF=65536],[CONF_TCP_SO_SNDBUF=65536])
AC_MSG_RESULT($CONF_TCP_SO_SNDBUF)
AC_DEFINE_UNQUOTED(CONF_TCP_SO_SNDBUF, $CONF_TCP_SO_SNDBUF, [default TCP send buffer])
AC_MSG_CHECKING(default TCP receive buffer size)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(void)
{
int fd,val=0,len=sizeof(int);
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) return 1;
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) < 0) return 1;
if (val <= 0) return 1;
fprintf (fopen("conftestval", "w"), "%d\n", val);
return 0;
}
]])],[CONF_TCP_SO_RCVBUF=`cat conftestval`],[CONF_TCP_SO_RCVBUF=65536],[CONF_TCP_SO_RCVBUF=65536])
AC_MSG_RESULT($CONF_TCP_SO_RCVBUF)
AC_DEFINE_UNQUOTED(CONF_TCP_SO_RCVBUF, $CONF_TCP_SO_RCVBUF, [defaut TCP receive buffer])
AC_ARG_WITH(ldap,
[AS_HELP_STRING(--with-ldap,Users database is an LDAP directory (see doc))],
[ if test "x$withval" != "xno" ; then
if test "x$withval" != "x" && test "x$withval" != "xyes" ; then
LD_RUN_PATH="${withval}/lib${LD_RUN_PATH:+:}${LD_RUN_PATH}"
LDFLAGS="$LDFLAGS -L${withval}/lib"
CPPFLAGS="$CPPFLAGS -I${withval}/include"
fi
with_ldap="yes"
AC_DEFINE(WITH_LDAP,,[with ldap])
AC_CHECK_LIB(resolv, res_query)
AC_CHECK_LIB(lber, ber_init, ,
[AC_MSG_ERROR(liblber is needed for LDAP support)])
AC_CHECK_LIB(ldap, ldap_init, ,
[AC_MSG_WARN(Initial check for -lldap failed! May need -lssl -lcrypto)
AC_CHECK_LIB(ldap, ldap_bind, [ldap_ssl_libs=true],
[AC_MSG_ERROR(libldap is needed for LDAP support)], -lssl -lcrypto)
])
if test "x$ldap_ssl_libs" = "xtrue" ; then
LDAP_SSL_LIBS='-lssl -lcrypto'
fi
fi ])
AC_SUBST(LDAP_SSL_LIBS)
AC_ARG_WITH(mysql,
[AS_HELP_STRING(--with-mysql,Users database is a MySQL database (see doc))],
[ if test "x$withval" != "xno" ; then
if test "x$withval" != "x" && test "x$withval" != "xyes" ; then
LD_RUN_PATH="${withval}/lib${LD_RUN_PATH:+:}${LD_RUN_PATH}"
LDFLAGS="$LDFLAGS -L${withval}/lib -L${withval}/lib/mysql -L${withval}/mysql/lib"
CPPFLAGS="$CPPFLAGS -I${withval}/include -I${withval}/include/mysql -I${withval}/mysql/include"
else
CFLAGS="$CFLAGS `mariadb_config --cflags 2> /dev/null || mysql_config --cflags`"
LDFLAGS="$LDFLAGS `mariadb_config --libs 2> /dev/null || mysql_config --libs`"
fi
AC_CHECK_LIB(m, floor)
AC_CHECK_LIB(z, gzclose)
with_mysql="yes"
AC_DEFINE(WITH_MYSQL,,[with mysql])
AC_CHECK_FUNC(mysql_init, , [
AC_CHECK_LIB(mariadb, mysql_init, , [
AC_CHECK_LIB(mysqlclient, mysql_init, ,
[AC_MSG_ERROR(libmysqlclient is needed for MySQL support)])
])
])
AC_MSG_CHECKING(whether mysql clients can run)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <mysql.h>
int main(void)
{
MYSQL *a = mysql_init(NULL);
return 0;
}
]])],[],[
AC_MSG_RESULT(no)
AC_MSG_ERROR(Your MySQL client libraries aren't properly installed)
],[])
AC_MSG_RESULT(yes)
fi ])
AC_ARG_WITH(pgsql,
[AS_HELP_STRING(--with-pgsql,Users database is a PostgreSQL database (see doc))],
[ if test "x$withval" != "xno" ; then
if test "x$withval" != "x" && test "x$withval" != "xyes" ; then
LD_RUN_PATH="${withval}/lib${LD_RUN_PATH:+:}${LD_RUN_PATH}"
LDFLAGS="$LDFLAGS -L${withval}/lib -L${withval}/lib/pgsql -L${withval}/lib/postgresql -L${withval}/pgsql/lib -L${withval}/postgresql/lib"
CPPFLAGS="$CPPFLAGS -I${withval}/include -I${withval}/include/pgsql -I${withval}/include/postgresql -I${withval}/pgsql/include -I${withval}/postgresql/include"
else
LD_RUN_PATH="`pg_config --libdir`${LD_RUN_PATH:+:}${LD_RUN_PATH}"
CPPFLAGS="$CPPFLAGS -I`pg_config --includedir`"
LDFLAGS="$LDFLAGS -L`pg_config --libdir`"
fi
AC_CHECK_LIB(m, floor)
AC_CHECK_LIB(z, gzclose)
with_pgsql="yes"
AC_DEFINE(WITH_PGSQL,,[with pgsql])
AC_CHECK_LIB(pq, PQconnectdb, ,
[AC_MSG_ERROR(libpq is needed for PostgreSQL support)])
AC_MSG_CHECKING(whether postgresql clients can run)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <libpq-fe.h>
int main(void)
{
PGconn *a = PQconnectdb("");
return 0;
}
]])],[],[
AC_MSG_RESULT(no)
AC_MSG_ERROR(Your PostgreSQL client libraries aren't properly installed)
],[])
AC_MSG_RESULT(yes)
fi ])
AC_ARG_WITH(tls,
[AS_HELP_STRING(--with-tls,Enable TLS support)],
[ if test "x$withval" = "xyes" ; then
with_tls="yes"
fi ])
if test "x$with_tls" = "xyes" ; then
if test "x$ac_cv_header_openssl_ssl_h" != "xyes" ; then
AC_MSG_ERROR(OpenSSL headers not found.)
fi
AC_CHECK_LIB(crypto, DH_new)
AC_CHECK_LIB(ssl, SSL_accept)
AC_CHECK_FUNCS(DH_get_2048_256)
AC_DEFINE(WITH_TLS,,[Enable TLS])
fi
AC_ARG_WITH(certfile,
[AS_HELP_STRING(--with-certfile=,certificate file (default: /etc/ssl/private/pure-ftpd.pem))],
[ if test "x$withval" != "x" ; then
certfile="$withval"
AC_SUBST(certfile)
CPPFLAGS="$CPPFLAGS -DTLS_CERTIFICATE_FILE='\"$certfile\"'"
if test ! -e "$certfile"; then
AC_MSG_WARN(No certificate is installed in $certfile yet)
fi
fi ])
AC_ARG_WITH(rfc2640,
[AS_HELP_STRING(--with-rfc2640,Enable RFC 2640 (UTF-8 encoding for file names) support (needs iconv))],
[ if test "x$withval" = "xyes" ; then
with_rfc2640="yes"
fi ])
if test "x$with_rfc2640" = "xyes" ; then
if test "x$ac_cv_header_iconv_h" != "xyes" ; then
AC_MSG_ERROR(iconv headers not found.)
fi
AC_CHECK_LIB(iconv, iconv_open)
AC_CHECK_LIB(iconv, libiconv_open)
AC_DEFINE(WITH_RFC2640,,[Enable RFC2640 (UTF-8) support])
fi
AC_ARG_WITH(bonjour,
[AS_HELP_STRING(--with-bonjour,Enable Bonjour support on MacOS X)],
[ if test "x$withval" = "xyes" ; then
with_bonjour="yes"
fi ])
if test "x$with_bonjour" = "xyes" ; then
if test "x$ac_cv_header_CoreFoundation_CoreFoundation_h" = "xyes" ; then
AC_DEFINE(WITH_BONJOUR,,[Enable Bonjour on MacOS X])
BONJOUR_LDADD='-framework CoreFoundation -framework CoreServices'
fi
fi
AC_SUBST(BONJOUR_LDADD)
if test "x$sysconfdir" = 'xNONE' || test "x$sysconfdir" = 'x'; then
CONFDIR='/etc'
else
if test "x$sysconfdir" = 'x${prefix}/etc'; then
if test "x$prefix" = 'xNONE' || test "x$prefix" = 'x/usr'; then
CONFDIR='/etc'
else
CONFDIR="$sysconfdir"
fi
else
CONFDIR="$sysconfdir"
fi
fi
if test "x$localstatedir" = 'xNONE' || test "x$localstatedir" = 'x'; then
LOCALSTATEDIR='/var'
else
if test "x$localstatedir" = 'x${prefix}/var'; then
if test "x$prefix" = 'xNONE' || test "x$prefix" = 'x/usr' || test "x$localstatedir" = 'x${prefix}/var' ; then
LOCALSTATEDIR='/var'
else
LOCALSTATEDIR="$localstatedir"
fi
else
LOCALSTATEDIR="$localstatedir"
fi
fi
if test -r /dev/urandom; then
AC_MSG_NOTICE([You have /dev/urandom - Great])
AC_DEFINE(HAVE_DEV_URANDOM,,[Define if you have /dev/urandom])
fi
if test -r /dev/random; then
AC_MSG_NOTICE([You have /dev/random - Great])
AC_DEFINE(HAVE_DEV_RANDOM,,[Define if you have /dev/random])
fi
CONFDIR=`eval echo "$CONFDIR"`
LOCALSTATEDIR=`eval echo "$LOCALSTATEDIR"`
sysconfdir="$CONFDIR"
AC_SUBST(sysconfdir)
localstatedir="$LOCALSTATEDIR"
AC_SUBST(localstatedir)
CPPFLAGS="$CPPFLAGS -DCONFDIR=\\\"$sysconfdir\\\""
CPPFLAGS="$CPPFLAGS -DSTATEDIR=\\\"$localstatedir\\\""
AC_SUBST(CONFDIR)
AC_SUBST(LOCALSTATEDIR)
AH_VERBATIM([NDEBUG], [/* Never ever ignore assertions */
#ifdef NDEBUG
#/**/undef/**/ NDEBUG
#endif])
增加输出文件。
AC_CONFIG_FILES([Makefile
gui/Makefile
m4/Makefile
man/Makefile
pam/Makefile
puredb/Makefile
puredb/src/Makefile
src/Makefile
pure-ftpd.conf
man/pure-ftpd.8
man/pure-ftpwho.8
man/pure-mrtginfo.8
man/pure-uploadscript.8
man/pure-statsdecode.8
man/pure-quotacheck.8
man/pure-pw.8
man/pure-pwconvert.8
man/pure-authd.8
])
输出configure消息信息
AC_MSG_NOTICE([+--------------------------------------------------------+])
AC_MSG_NOTICE([| You can subscribe to the Pure-FTPd users mailing-list |])
AC_MSG_NOTICE([| to ask for help and to stay informed of new releases. |])
AC_MSG_NOTICE([| Go to http://www.pureftpd.org/ml/ now! |])
AC_MSG_NOTICE([+--------------------------------------------------------+])