1#library checks for preloading code
2
3#A good time to save the cache (preload code might fail)
4AC_CACHE_SAVE
5
6SOLIB_POSTFIX=so
7unset SOFULLPATH
8
9case $host in
10    *-*-aix*)
11	PRELOAD="LDR"
12	SOLIB_POSTFIX="a(shr.o)"
13	#XXX final part might vary, LDR_PRELOAD64 shr_64.o?
14	#XXX libdsocks_64.so or similar for 64 bit
15	#XXX extra variable for last part (not part of file name)
16	SOFULLPATH=t
17	;;
18
19    alpha*-dec-osf*)
20	AC_DEFINE(HAVE_DEC_PROTO, 1, [DEC workarounds])
21	AC_DEFINE(HAVE_EXTRA_OSF_SYMBOLS, 1, [DEC workarounds])
22	PRELOAD="RLD"
23	;;
24
25    *-*-hpux*)
26	SOLIB_POSTFIX=sl
27	;;
28
29    *-*-darwin*)
30	SOLIB_POSTFIX=dylib
31	PRELOAD="DYLD"
32	SOFULLPATH=t
33	;;
34
35    *-*-irix*)
36	PRELOAD="RLD"
37	;;
38
39    *-*-cygwin)
40	AC_MSG_WARN([disabling preloading])
41	no_preload_client=t
42	no_preload_server=t
43	no_preload=t
44	AC_DEFINE(HAVE_NO_RESOLVESTUFF, 1, [primitive platform])
45	;;
46esac
47
48AC_SUBST(SOLIB_POSTFIX)
49
50case $PRELOAD in
51    DYLD)
52	PRELOAD_SEPERATOR=":"
53	PRELOAD_VARIABLE="DYLD_INSERT_LIBRARIES"
54	PRELOAD_POSTFIX=""
55	;;
56
57    RLD)
58	PRELOAD_SEPERATOR=":"
59	PRELOAD_VARIABLE="_RLD_LIST"
60	PRELOAD_POSTFIX="DEFAULT"
61	;;
62
63    LDR)
64	PRELOAD_SEPERATOR=":"
65	PRELOAD_VARIABLE="LDR_PRELOAD"
66	PRELOAD_POSTFIX=""
67	;;
68
69    *)
70	PRELOAD_SEPERATOR=" "
71	PRELOAD_VARIABLE="LD_PRELOAD"
72	PRELOAD_POSTFIX=""
73	;;
74esac
75
76AC_SUBST(PRELOAD_SEPERATOR)
77AC_SUBST(PRELOAD_VARIABLE)
78AC_SUBST(PRELOAD_POSTFIX)
79
80## preload related tests
81#build without support for preloading?
82
83AC_MSG_CHECKING([for RES_INIT in resolv.h])
84AC_TRY_COMPILE([
85#include <sys/types.h>
86#include <netinet/in.h>
87#include <arpa/nameser.h>
88#include <resolv.h>
89], [
90#ifndef RES_INIT
91#error "no RES_INIT"
92#endif],
93 [AC_MSG_RESULT(yes)],
94 [AC_MSG_RESULT(no)
95  AC_DEFINE(HAVE_NO_RESOLVESTUFF, 1, [primitive platform])])
96
97# HAVE_DLFCN_H only determines if the include file exists
98AC_CHECK_HEADER(dlfcn.h,
99[AC_DEFINE(HAVE_DLFCN_H, 1, [dlfcn.h exists])
100 have_dlfcn_h=t],
101[AC_MSG_WARN([dlfcn.h missing, preloading disabled])
102 no_preload_client=t
103 no_preload_server=t
104 no_preload=t])
105
106if test x"${no_preload}" = x; then
107    AC_MSG_CHECKING([whether all interposition usage should be disabled])
108    AC_ARG_ENABLE(preload,
109	[  --disable-preload       disable preloading in server and client],
110	[if test x"$enableval" = xno; then
111	     no_preload_client=t
112	     no_preload_server=t
113	     no_preload=t
114	     AC_MSG_RESULT([yes])
115	 else
116	     AC_MSG_RESULT([no])
117	 fi],[AC_MSG_RESULT([no])])
118fi
119
120if test x"${no_preload}" = x; then
121    AC_MSG_CHECKING([whether interposition in the client should be disabled])
122    AC_ARG_ENABLE(clientdl,
123	[  --disable-clientdl      disable support for preloading in the client],
124	[if test x"$enableval" = xno; then
125             no_preload_client=t
126	     AC_MSG_RESULT([yes])
127         else
128             AC_MSG_RESULT([no])
129	 fi], [AC_MSG_RESULT([no])])
130
131    AC_MSG_CHECKING([whether interposition in the server should be disabled])
132    AC_ARG_ENABLE(serverdl,
133	[  --disable-serverdl      disable support for preloading in the server],
134	[if test x"$enableval" = xno; then
135             no_preload_server=t
136	     AC_MSG_RESULT([yes])
137         else
138             if test x"$enableval" = xyes; then
139		 serverdl_always_on=t
140	     fi
141	     AC_MSG_RESULT([no])
142	 fi], [AC_MSG_RESULT([no])])
143fi
144
145AM_CONDITIONAL(SERVER_INTERPOSITION, test x"$no_preload_server" = x)
146AM_CONDITIONAL(SERVER_INTERPOSITION_ALWAYS, test x"$serverdl_always_on" = xt)
147
148if test x"${no_preload_client}" = xt -a x"${no_preload_server}" = xt; then
149    unset preload_enabled
150else
151    preload_enabled=t
152fi
153
154unset have_dlflag
155AC_MSG_CHECKING([for DL_LAZY])
156AC_EGREP_CPP(yes, [
157#include <dlfcn.h>
158#ifdef DL_LAZY
159yes
160#endif
161], [AC_MSG_RESULT(yes)
162    have_dlflag=t],
163   [AC_MSG_RESULT(no)])
164
165if test x"${have_dlflag}" = x; then
166    AC_MSG_CHECKING([for RTLD_MEMBER])
167    AC_EGREP_CPP(yes, [
168#include <dlfcn.h>
169#ifdef RTLD_MEMBER
170# ifdef RTLD_LAZY
171yes
172# endif
173#endif
174    ], [AC_DEFINE(DL_LAZY, RTLD_LAZY|RTLD_MEMBER, [dlopen with RTLD_MEMBER])
175	AC_MSG_RESULT(yes)
176	have_dlflag=t],
177       [AC_MSG_RESULT(no)])
178fi
179
180if test x"${have_dlflag}" = x; then
181    AC_MSG_CHECKING([to see if dlopen param has DL_ and not RTLD_ prefix])
182    AC_EGREP_CPP(yes, [
183#include <dlfcn.h>
184#ifdef DL_LAZY
185#else
186# ifdef RTLD_LAZY
187yes
188# endif
189#endif
190    ], [AC_DEFINE(DL_LAZY, RTLD_LAZY, [dlopen has RTLD_ prefix])
191	AC_MSG_RESULT(yes)
192	have_dlflag=t],
193       [AC_MSG_RESULT(no)])
194fi
195
196dnl XXX Some Linux specific calls - possibly more required
197AC_CHECK_FUNCS(__fprintf_chk __vfprintf_chk __read_chk)
198
199dnl XXX Some Linux glibc getc,putc replacements
200AC_CHECK_FUNCS(_IO_getc _IO_putc)
201
202AC_SEARCH_LIBS(getaddrinfo, socket)
203AC_SEARCH_LIBS(getnameinfo, socket)
204AC_CHECK_FUNCS(gethostbyname2 getaddrinfo getnameinfo freeaddrinfo)
205AC_CHECK_FUNCS(getipnodebyname)
206
207#find prototypes from dlib/interposition.c
208if test x"${preload_enabled}" = xt; then
209
210    unset failproto
211    preprotoCFLAGS="$CFLAGS"
212#   CFLAGS="$CFLAGS -Werror"
213
214    #prototypes; return value first, then parameters
215    #
216    # Example (accept from OpenBSD manual page):
217    #
218    # int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
219    #
220    # Remove variable names and the result is:
221    # int, int, struct sockaddr *, socklen_t *
222    # This is quoted and added to the L_NSOCKPROTO call below.
223
224    L_NSOCKPROTO(accept, [failproto=t],
225	[int, int, struct sockaddr *, socklen_t *],
226	[int, int, struct sockaddr *, Psocklen_t])
227
228    L_NSOCKPROTO(bind, [failproto=t],
229	[int, int, const struct sockaddr *, socklen_t])
230
231    L_NSOCKPROTO(connect, [failproto=t],
232	[int, int, const struct sockaddr *, socklen_t])
233
234    L_NSOCKPROTO(gethostbyaddr, [failproto=t],
235	[struct hostent *, const char *, int, int],
236	[struct hostent *, const char *, socklen_t, int],
237	[struct hostent *, const void *, socklen_t, int],
238	[struct hostent *, const void *, int, int],
239	[struct hostent *, const void *, size_t, int])
240
241     L_NSOCKPROTO(getnameinfo, [failproto=t],
242        [int, const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, int],
243        [int, const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t,  unsigned int],
244        [int, const struct sockaddr *, socklen_t, char *, size_t, char *, size_t,    int])
245
246    L_NSOCKPROTO(getpeername, [failproto=t],
247	[int, int, struct sockaddr *, socklen_t *],
248	[int, int, struct sockaddr *, Psocklen_t])
249
250    L_NSOCKPROTO(getsockname, [failproto=t],
251	[int, int, struct sockaddr *, socklen_t *],
252	[int, int, struct sockaddr *, Psocklen_t])
253
254    L_NSOCKPROTO(getsockopt, [failproto=t],
255	[int, int, int, int, void *, socklen_t *],
256	[int, int, int, int, void *, Psocklen_t],
257	[int, int, int, int, char *, int *])
258
259    L_NSOCKPROTO(listen, [failproto=t],
260	[int, int, int])
261
262    L_NSOCKPROTO(read, [failproto=t],
263	[ssize_t, int, void *, size_t])
264
265    L_NSOCKPROTO(readv, [failproto=t],
266	[ssize_t, int, const struct iovec *, int],
267	[int, int, const struct iovec *, int])
268
269    L_NSOCKPROTO(recv, [failproto=t],
270	[ssize_t, int, void *, size_t, int],
271	[ssize_t, int, void *, size_t, unsigned int])
272
273    L_NSOCKPROTO(recvfrom, [failproto=t],
274	[ssize_t, int, void *, size_t, int, struct sockaddr *, socklen_t *],
275	[ssize_t, int, void *, size_t, int, struct sockaddr *, Psocklen_t],
276	[ssize_t, int, void *, size_t, unsigned int, const struct sockaddr *, socklen_t *])
277
278    L_NSOCKPROTO(recvmsg, [failproto=t],
279	[ssize_t, int, struct msghdr *, int],
280	[int, int, struct msghdr *, unsigned int])
281
282    L_NSOCKPROTO(send, [failproto=t],
283	[ssize_t, int, const void *, size_t, int],
284	[ssize_t, int, const void *, size_t, unsigned int])
285
286    L_NSOCKPROTO(sendmsg, [failproto=t],
287	[ssize_t, int, const struct msghdr *, int],
288	[int, int, const struct msghdr *, unsigned int])
289
290    L_NSOCKPROTO(sendto, [failproto=t],
291	[ssize_t, int, const void *, size_t, int, const struct sockaddr *, socklen_t])
292
293    L_NSOCKPROTO(write, [failproto=t],
294	[ssize_t, int, const void *, size_t])
295
296    L_NSOCKPROTO(writev, [failproto=t],
297	[ssize_t, int, const struct iovec *, int],
298	[int, int, const struct iovec *, int])
299
300    #XXX stdio related functions
301    L_NSTDIOPROTO(getc, [failproto=t],
302	[int, FILE *])
303
304    L_NSTDIOPROTO(fgetc, [failproto=t],
305	[int, FILE *])
306
307    L_NSTDIOPROTO(gets, [failproto=t],
308	[char *, char *])
309
310    L_NSTDIOPROTO(fgets, [failproto=t],
311	[char *, char *, int, FILE *])
312
313    L_NSTDIOPROTO(putc, [failproto=t],
314	[int, int, FILE *])
315
316    L_NSTDIOPROTO(fputc, [failproto=t],
317	[int, int, FILE *])
318
319    L_NSTDIOPROTO(puts, [failproto=t],
320	[int, const char *])
321
322    L_NSTDIOPROTO(fputs, [failproto=t],
323	[int, const char *, FILE *])
324
325    L_NSTDIOPROTO(fflush, [failproto=t],
326	[int, FILE *])
327
328    L_NSTDIOPROTO(fclose, [failproto=t],
329	[int, FILE *])
330
331    L_NSTDIOPROTO(fprintf, [failproto=t],
332	[int, FILE *, const char *, ...])
333
334    L_NSTDIOPROTO(vfprintf, [failproto=t],
335	[int, FILE *, const char *, va_list])
336
337    L_NSTDIOPROTO(printf, [failproto=t],
338	[int, const char *, ...])
339
340    L_NSTDIOPROTO(vprintf, [failproto=t],
341	[int, const char *, va_list])
342
343    L_NSTDIOPROTO(fwrite, [failproto=t],
344	[size_t, const void *, size_t, size_t, FILE *])
345
346    L_NSTDIOPROTO(fread, [failproto=t],
347	[size_t, void *, size_t, size_t, FILE *])
348
349    if test x"${ac_cv_func__IO_getc}" = xyes; then
350	L_NSTDIOPROTO(_IO_getc, [failproto=t],
351	    [int, FILE *])
352    fi
353
354    if test x"${ac_cv_func__IO_putc}" = xyes; then
355	L_NSTDIOPROTO(_IO_putc, [failproto=t],
356	    [int, int, FILE *])
357    fi
358
359    if test x"${ac_cv_func___read_chk}" = xyes; then
360	L_NSTDIOPROTO(_read_chk, [failproto=t],
361	    [ssize_t, int, void *, size_t, size_t])
362    fi
363
364    #XXX add vprintf_chk/fprintf_chk?
365
366    if test x"$failproto" != x; then
367	AC_MSG_WARN([attempt to determine function prototypes
368failed, and will probably mean that building of libdsocks, which
369allows on-the-fly socksification of dynamic binaries, will not work.
370
371      You have several options:
372
373      1. If you do not need libdsocks, run configure with the
374         option --disable-preload.
375      2. Submit a bugreport.
376      3. Find the prototypes used on your platform for the
377         failed functions, and add them to the configure.ac
378         file. Then use autoconf, which must be installed,
379         to regenerate the configure script.
380         Function prototype definitions can usually be found
381         in the manual page for the function or the system
382         include files (usually found under /usr/include).])
383	exit 1
384    fi
385
386    CFLAGS="$preprotoCFLAGS"
387fi
388
389#Look for functions needed for socksify located in other places than libc
390SOCKSIFY_PRELOAD_LIBS=""
391oLIBS=$LIBS
392
393#clock_gettime()
394if test x"${ac_cv_search_clock_gettime}" = x"-lrt"; then
395    SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${SOCKSIFY_PRELOAD_LIBS:+${PRELOAD_SEPERATOR}}${base_library_path}librt.${SOLIB_POSTFIX}"
396fi
397
398#HP-UX 11.00
399LIBS=""
400AC_SEARCH_LIBS(bindresvport, rpcsoc)
401
402NLIBS="${NLIBS}${NLIBS:+ }$LIBS"
403LIBS=""
404
405#ignore when preloading is disabled (only the AC_SEARCH_LIBS test is needed)
406if test x"${preload_enabled}" = xt -a x"${ac_cv_search_bindresvport}" = x"-lrpcsoc"; then
407    AC_DEFINE_UNQUOTED(LIBRARY_LIBRPCSOC, "${base_library_path}librpcsoc.sl", [libname])
408    SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${SOCKSIFY_PRELOAD_LIBS:+${PRELOAD_SEPERATOR}}${base_library_path}librpcsoc.sl"
409
410    AC_DEFINE(LIBRARY_BINDRESVPORT, LIBRARY_LIBRPCSOC, [function loc])
411fi
412
413unset use_threads
414unset have_ptread_h
415AC_CHECK_HEADER(pthread.h,
416    [AC_DEFINE(HAVE_PTHREAD_H, 1, [have pthread header])
417     have_pthread_h=t])
418if test x"${have_pthread_h}" = xt; then
419    #do not wish to link directly with libpthreads, included only if needed
420    tLIBS=$LIBS
421    AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
422
423    #try compiling
424    AC_MSG_CHECKING([whether compilation with pthread.h works])
425    AC_TRY_LINK([
426#include <pthread.h>], [
427pthread_mutexattr_t attr;
428if (pthread_mutexattr_init(&attr) == 0)
429    return 0;
430else
431    return 1;],
432	[AC_MSG_RESULT(yes)
433	 use_threads=t],
434	[AC_MSG_RESULT(no)])
435    LIBS=$tLIBS
436fi
437if test x"$use_threads" = xt; then
438    AC_DEFINE(HAVE_PTHREAD_H, 1, [have pthread header])
439    if test x"${ac_cv_search_pthread_mutexattr_init}" = x"-lpthread"; then
440        case $host in
441	    *-*-linux-*)
442	        #XXX attempt to find latest pthread library
443		PATH=$PATH:/sbin
444		export PATH
445		unset LIBPT_ALTS
446		for file in `ldconfig -p | grep /libpthread.so| xargs -n 1 echo | grep /libpthread.so`; do
447		    test -s "$file" && LIBPT_ALTS="${LIBPT_ALTS}${LIBPT_ALTS:+ }$file"
448		done
449		LIBPT_NAME=`echo ${LIBPT_ALTS} | sed -e 's/.*\///' | sort -nr | head -n 1`
450		if test x"${LIBPT_NAME}" = x; then
451		    #nothing found, set something anyway
452		    LIBPT_NAME="${base_library_path}libpthread.so"
453		fi
454		;;
455
456	    *)
457		LIBPT_NAME="libpthread.${SOLIB_POSTFIX}"
458		;;
459        esac
460        AC_DEFINE_UNQUOTED(LIBRARY_PTHREAD, "${base_library_path}$LIBPT_NAME", [libloc])
461    fi
462fi
463
464LIBS=""
465AC_SEARCH_LIBS(connect, socket)
466#ignore when preloading is disabled (only the AC_SEARCH_LIBS test is needed)
467if test x"$preload_enabled" = xt -a x"${ac_cv_search_connect}" = x"-lsocket"; then
468    AC_DEFINE_UNQUOTED(LIBRARY_LIBSOCKET, "${base_library_path}libsocket.${SOLIB_POSTFIX}", [libloc])
469    SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${SOCKSIFY_PRELOAD_LIBS:+${PRELOAD_SEPERATOR}}${base_library_path}libsocket.${SOLIB_POSTFIX}"
470
471    AC_DEFINE(LIBRARY_CONNECT, LIBRARY_LIBSOCKET, [function loc])
472
473    AC_CHECK_LIB(socket, accept,
474	AC_DEFINE(LIBRARY_ACCEPT, LIBRARY_LIBSOCKET, [function loc]))
475    AC_CHECK_LIB(socket, bind,
476	AC_DEFINE(LIBRARY_BIND, LIBRARY_LIBSOCKET, [function loc]))
477    AC_CHECK_LIB(socket, bindresvport,
478	AC_DEFINE(LIBRARY_BINDRESVPORT, LIBRARY_LIBSOCKET, [function loc]))
479    AC_CHECK_LIB(socket, getpeername,
480	AC_DEFINE(LIBRARY_GETPEERNAME, LIBRARY_LIBSOCKET, [function loc]))
481    AC_CHECK_LIB(socket, getsockname,
482	AC_DEFINE(LIBRARY_GETSOCKNAME, LIBRARY_LIBSOCKET, [function loc]))
483    AC_CHECK_LIB(socket, listen,
484	AC_DEFINE(LIBRARY_LISTEN, LIBRARY_LIBSOCKET, [function loc]))
485    AC_CHECK_LIB(socket, getaddrinfo,
486	AC_DEFINE(LIBRARY_GETADDRINFO, LIBRARY_LIBSOCKET, [function loc]))
487    AC_CHECK_LIB(socket, getnameinfo,
488        AC_DEFINE(LIBRARY_GETNAMEINFO, LIBRARY_LIBSOCKET, [function loc]))
489    AC_CHECK_LIB(socket, freeaddrinfo,
490	AC_DEFINE(LIBRARY_FREEADDRINFO, LIBRARY_LIBSOCKET, [function loc]))
491    AC_CHECK_LIB(socket, freehostent,
492	AC_DEFINE(LIBRARY_FREEHOSTENT, LIBRARY_LIBSOCKET, [function loc]))
493    AC_CHECK_LIB(socket, recvfrom,
494	AC_DEFINE(LIBRARY_RECVFROM, LIBRARY_LIBSOCKET, [function loc]))
495    AC_CHECK_LIB(socket, rresvport,
496	AC_DEFINE(LIBRARY_RRESVPORT, LIBRARY_LIBSOCKET, [function loc]))
497    AC_CHECK_LIB(socket, recvmsg,
498	AC_DEFINE(LIBRARY_RECVMSG, LIBRARY_LIBSOCKET, [function loc]))
499    AC_CHECK_LIB(socket, sendmsg,
500	AC_DEFINE(LIBRARY_SENDMSG, LIBRARY_LIBSOCKET, [function loc]))
501    AC_CHECK_LIB(socket, send,
502	AC_DEFINE(LIBRARY_SEND, LIBRARY_LIBSOCKET, [function loc]))
503    AC_CHECK_LIB(socket, recv,
504	AC_DEFINE(LIBRARY_RECV, LIBRARY_LIBSOCKET, [function loc]))
505    AC_CHECK_LIB(socket, sendto,
506	AC_DEFINE(LIBRARY_SENDTO, LIBRARY_LIBSOCKET, [function loc]))
507fi
508
509NLIBS="${NLIBS}${NLIBS:+ }$LIBS"
510LIBS=""
511
512if test x"$preload_enabled" = xt -a x"${ac_cv_search_inet_addr}" = x"-lnsl"; then
513    AC_DEFINE_UNQUOTED(LIBRARY_LIBNSL, "${base_library_path}libnsl.${SOLIB_POSTFIX}", [libloc])
514
515    SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${SOCKSIFY_PRELOAD_LIBS:+${PRELOAD_SEPERATOR}}${base_library_path}libnsl.${SOLIB_POSTFIX}"
516
517    AC_CHECK_LIB(nsl, gethostbyname,
518	[AC_DEFINE(LIBRARY_GETHOSTBYNAME, LIBRARY_LIBNSL, [function loc])])
519    AC_CHECK_LIB(nsl, gethostbyaddr,
520	[AC_DEFINE(LIBRARY_GETHOSTBYADDR, LIBRARY_LIBNSL, [function loc])])
521    AC_CHECK_LIB(nsl, freehostent,
522	AC_DEFINE(LIBRARY_FREEHOSTENT, LIBRARY_LIBNSL, [function loc]))
523    AC_CHECK_LIB(nsl, getipnodebyname,
524	[AC_DEFINE(LIBRARY_GETIPNODEBYNAME, LIBRARY_LIBNSL, [function loc])])
525fi
526
527#linking with -lresolv results in error unless -shared is included
528#since no static version exists for libresolv on SunOS
529AC_SEARCH_LIBS(inet_aton, resolv)
530
531AC_SEARCH_LIBS(res_9_init, resolv)
532
533NLIBS="${NLIBS}${NLIBS:+ }$LIBS"
534LIBS=""
535
536if test x"${preload_enabled}" = xt -a x"${ac_cv_search_inet_aton}" = x"-lresolv"; then
537    AC_DEFINE_UNQUOTED(LIBRARY_LIBRESOLV, "${base_library_path}libresolv.${SOLIB_POSTFIX}", [libloc])
538
539    SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${SOCKSIFY_PRELOAD_LIBS:+${PRELOAD_SEPERATOR}}${base_library_path}libresolv.${SOLIB_POSTFIX}"
540
541    AC_CHECK_LIB(resolv, gethostbyname2,
542	[AC_DEFINE(LIBRARY_GETHOSTBYNAME2, LIBRARY_LIBRESOLV, [function loc])])
543fi
544
545#XXX gcc on Solaris (using gnu ld) doesn't seems to implicitly link
546#with libdl in this test, which means that libdl will not be included
547#in socksify.
548
549if test x"${preload_enabled}" = xt; then
550    AC_SEARCH_LIBS(dlopen, dl)
551
552    NLIBS="${NLIBS}${NLIBS:+ }$LIBS"
553    LIBS=""
554    if test x"${ac_cv_search_dlopen}" = x"-ldl"; then
555	case $host in
556	    *-*-sunos4*) #XXX attempt to get libdl name
557		libdl=`ls ${base_library_path}libdl.${SOLIB_POSTFIX}* | sed -e 's/.*\///' | sort -nr | head -n 1`
558		if test x"$libdl" = x; then
559		    AC_MSG_WARN([unable to locate libdl])
560		else
561		    LIBRARY_DLOPEN=${base_library_path}${libdl}
562		    AC_MSG_WARN([hardcoding libdl to $LIBRARY_DLOPEN])
563		fi
564		;;
565
566	    *)
567		LIBRARY_DLOPEN="${base_library_path}libdl.${SOLIB_POSTFIX}"
568		;;
569	esac
570	SOCKSIFY_PRELOAD_LIBS="${SOCKSIFY_PRELOAD_LIBS}${LIBRARY_DLOPEN:+${PRELOAD_SEPERATOR}}${LIBRARY_DLOPEN}"
571    fi
572fi
573LIBS="$oLIBS $NLIBS"
574
575AC_SUBST(SOCKSIFY_PRELOAD_LIBS)
576
577AC_CHECK_FUNCS(rresvport) #not found on android
578
579#specify location of the socks library in socksify too
580#NOTE: exec_prefix and prefix have the value NONE here if they are unset
581o_exec_prefix=${exec_prefix}
582o_prefix=${prefix}
583if test x"${prefix}" = xNONE; then
584    prefix=$ac_default_prefix
585fi
586if test x"${exec_prefix}" = xNONE; then
587    exec_prefix=$prefix
588fi
589LIBRARY_PREFIX=`eval echo \$libdir`
590LIBRARY_PREFIX=`eval echo \$LIBRARY_PREFIX`
591exec_prefix=${o_exec_prefix}
592prefix=${o_prefix}
593AC_SUBST(LIBRARY_PREFIX)
594
595#allow user to specify libc name, use default value otherwise
596AC_MSG_CHECKING([for libc name])
597AC_ARG_WITH(libc,
598    [  --with-libc=NAME        manually set name of c library if necessary],
599    [LIBC_NAME=$withval])
600
601#set default?
602if test x"${LIBC_NAME}" = x; then
603    case $host in
604	*-*-freebsd*)
605	    #XXX
606	    #can't set it to libc.so directly, might be ld script
607	    unset LIBC_ALTS
608	    for file in `ldconfig -r | grep /libc.so| awk '{ print $3 }'`; do
609		test -s "$file" && LIBC_ALTS="${LIBC_ALTS}${LIBC_ALTS:+ }$file"
610	    done
611	    LIBC_NAME=`echo ${LIBC_ALTS} | sed -e 's/.*\///' | sort -nr | head -n 1`
612	    if test x"${LIBC_NAME}" = x; then
613		#nothing found, set libc.so anyway
614		LIBC_NAME="${base_library_path}libc.${SOLIB_POSTFIX}"
615	    fi
616	    ;;
617
618	*-*-linux-*)
619	    #XXX
620	    #can't set it to libc.so directly, might be ld script
621	    unset LIBC_ALTS
622	    for file in `ldconfig -p | grep /libc.so| xargs -n 1 echo | grep /libc.so`; do
623		test -s "$file" && LIBC_ALTS="${LIBC_ALTS}${LIBC_ALTS:+ }$file"
624	    done
625	    LIBC_NAME=`echo ${LIBC_ALTS} | sed -e 's/.*\///' | sort -nr | head -n 1`
626	    if test x"${LIBC_NAME}" = x; then
627		#nothing found, set libc.so anyway
628		LIBC_NAME="${base_library_path}libc.so"
629	    fi
630	    ;;
631
632	*)
633	    LIBC_NAME="${base_library_path}libc.${SOLIB_POSTFIX}"
634	    ;;
635    esac
636fi
637
638AC_MSG_RESULT(${LIBC_NAME})
639if test x"${LIBC_NAME}" = xNULL; then
640    AC_DEFINE(LIBRARY_LIBC, NULL, [libc name])
641else
642    AC_DEFINE_UNQUOTED(LIBRARY_LIBC, "${LIBC_NAME}", [libc name])
643fi
644
645AC_MSG_CHECKING([for symbol lookup without underscore])
646AC_TRY_RUN([
647#include <dlfcn.h>
648#include <stdio.h>
649
650#include "include/symbols.h"
651
652int main()
653{
654    void *lib;
655    void *sym;
656
657    if ((lib = dlopen(LIBRARY_CONNECT, DL_LAZY)) == NULL) {
658	    fprintf(stderr, "dlopen: %s\n", dlerror());
659	    return 1;
660    }
661    (void)dlerror();
662    if ((sym = dlsym(lib, "connect")) == NULL) {
663	    fprintf(stderr, "dlsym: %s\n", dlerror());
664	    return 1;
665    }
666    return 0;
667}], [AC_MSG_RESULT(yes)
668	AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE, 1, [underscores not needed])],
669    [AC_MSG_RESULT(no)],
670    [dnl XXX assume no underscore, should use env, e.g. CROSS_HAVE...
671	AC_MSG_RESULT(yes)
672	AC_DEFINE(HAVE_NO_SYMBOL_UNDERSCORE, 1, [underscores not needed])])
673
674AC_MSG_CHECKING([for working dlsym])
675AC_TRY_RUN([
676#include <dlfcn.h>
677#include <stdio.h>
678
679#include "include/symbols.h"
680
681int main()
682{
683    void *lib;
684    void *sym;
685
686    if ((lib = dlopen(LIBRARY_CONNECT, DL_LAZY)) == NULL) {
687	    fprintf(stderr, "dlopen: %s\n", dlerror());
688	    return 1;
689    }
690    (void)dlerror();
691    if ((sym = dlsym(lib, SYMBOL_CONNECT)) == NULL) {
692	    fprintf(stderr, "dlsym: %s\n", dlerror());
693	    return 1;
694    }
695    return 0;
696}], [AC_MSG_RESULT(yes)],
697    [AC_MSG_RESULT(no)
698     no_preload_client=t
699     no_preload_server=t
700     no_preload=t],
701    [dnl XXX assume yes when cross compiling
702     AC_MSG_RESULT(assuming yes)])
703
704AC_MSG_CHECKING([for working RTLD_NEXT])
705AC_TRY_RUN([
706#define _GNU_SOURCE
707#include <dlfcn.h>
708#include <stdio.h>
709
710#include "include/symbols.h"
711
712int main()
713{
714    void *sym;
715
716    if ((sym = dlsym(RTLD_NEXT, SYMBOL_READ)) == NULL) {
717	    fprintf(stderr, "dlsym: %s\n", dlerror());
718	    return 1;
719    }
720    return 0;
721}], [AC_MSG_RESULT(yes)
722     AC_DEFINE(HAVE_RTLD_NEXT, 1, [have working dlsym RTLD_NEXT])],
723    [AC_MSG_RESULT(no)
724     AC_DEFINE(HAVE_RTLD_NEXT, 0, [no working dlsym RTLD_NEXT])],
725    [dnl XXX assume yes when cross compiling
726     AC_MSG_RESULT(yes)
727     AC_DEFINE(HAVE_RTLD_NEXT, 1, [have working dlsym RTLD_NEXT])])
728
729if test x"${preload_enabled}" = xt; then
730    #Solaris might block preloading
731    AC_MSG_CHECKING([libc preload blocking])
732    AC_TRY_RUN([
733#include <stdlib.h>
734#include <string.h>
735#include <unistd.h>
736int
737main(int argc, char *argv[])
738{
739   char buf[1024];
740
741   strcpy(buf, "lari -V ");
742   strcat(buf, argv[0]);
743   strcat(buf, " | grep read | grep protected > /dev/null");
744
745   /*
746    * return error if 'protected'
747    * (ignore errors, not indicative of blocking) */
748   if (system(buf) == 0)
749      return 1;
750   else
751      return 0;
752}
753
754ssize_t
755read(d, buf, nbytes)
756   int d;
757   void *buf;
758   size_t nbytes;
759{
760   return 0;
761}
762], [AC_MSG_RESULT(no)],
763   [AC_MSG_RESULT(yes)
764    AC_MSG_WARN([this platform blocks preloading of libraries])
765    blocked_preload=t],
766   [dnl assuming no when cross compiling
767    AC_MSG_RESULT(assuming no)])
768fi
769
770unset NOPRELOAD
771if test x"${no_preload}" != x -o x"${no_preload_client}" != x; then
772   NOPRELOAD=t
773   FEAT="$FEAT${FEAT:+ }nopreload"
774else
775   AC_DEFINE(HAVE_PRELOAD, 1, [preloading enabled])
776fi
777AC_SUBST(NOPRELOAD)
778
779AC_SUBST(SOFULLPATH)
780
781AC_CONFIG_FILES(bin/socksify)
782
783#look for missing prototypes
784if test x"${ac_cv_func__IO_getc}" = xyes; then
785   AC_CHECK_DECLS([_IO_getc, _IO_putc])
786fi
787AC_CHECK_DECLS([gets])
788