1#!/usr/bin/env bash
2
3ssl_include_path() {
4    case "$(uname)" in
5	MINGW32*)
6	    echo /mingw32/include/openssl;;
7	MINGW64*)
8	    echo /mingw64/include/openssl;;
9	*)
10	    echo "${with_openssl:-/usr}/include/openssl"
11	    ;;
12    esac
13}
14
15freebsd_pkg_version() {
16    local pkg ver
17
18    for pkg in "$@"; do
19	ver=$(pkg info "$pkg" 2>/dev/null |
20		     sed -n 's/^Version[[:blank:]]*:[[:blank:]]*//p') &&
21	    [ -n "$ver" ] && echo "$ver" && return
22    done
23    return 1
24}
25
26branch_name="$1"
27shift
28
29is_5_7_or_above="false"
30is_5_8_or_above="false"
31if [ "${branch_name#master}" != "${branch_name}" ]; then
32  is_5_8_or_above="true"
33  is_5_7_or_above="true"
34elif [ "${branch_name#V5-7-}" != "${branch_name}" ]; then
35  is_5_7_or_above="true"
36fi
37
38libatmver="$(for p in linux-atm-devel; do
39                rpm -q --qf '%{version}\n' $p 2>/dev/null |
40                  grep -v 'not installed';
41              done |
42              head -n1;
43	      for p in libatm1-dev; do
44	        dpkg-query --show -f '${Version}\n' $p 2>/dev/null;
45              done | grep -v '^$';
46              pacman -Q no-such-library 2>/dev/null |
47                sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')"
48echo "libatmver=$libatmver"
49
50libmysqlver="$(for p in libmariadb-devel; do
51                rpm -q --qf '%{version}\n' $p 2>/dev/null |
52                  grep -v 'not installed';
53              done |
54              head -n1;
55	      for p in libmariadbclient-dev libmariadb-client-lgpl-dev; do
56	        dpkg-query --show -f '${Version}\n' $p 2>/dev/null;
57              done | grep -v '^$';
58              pacman -Q mingw-w64-x86_64-libmariadbclient 2>/dev/null |
59                sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')"
60echo "libmysqlver=$libmysqlver"
61
62libsensorsver="$(for p in libsensors4-devel; do
63                rpm -q --qf '%{version}\n' $p 2>/dev/null |
64                  grep -v 'not installed';
65              done |
66              head -n1;
67	      for p in libsensors4-dev; do
68	        dpkg-query --show -f '${Version}\n' $p 2>/dev/null;
69              done | grep -v '^$';
70              pacman -Q no-such-package 2>/dev/null |
71                sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')"
72echo "libsensorsver=$libsensorsver"
73
74if ! echo "$*" | grep -Eq 'with-openssl=(no|internal)|without-openssl'; then
75    case "$(uname -a)" in
76	FreeBSD*)
77	    opensslver="$(freebsd_pkg_version libressl-devel openssl111 openssl\
78	                  2>/dev/null)"
79	    if [ -z "$opensslver" ]; then
80		opensslver="$(openssl version 2>&1 |
81				{ read -r a b c; echo "$b"; })"
82	    fi
83	    ;;
84	Linux*)
85	    opensslver="$(
86	    for p in openssl-devel libopenssl-devel libressl-devel; do
87	      rpm -q --qf '%{version}\n' $p 2>/dev/null |
88                grep -v 'not installed';
89            done;
90	    dpkg-query --show -f '${Version}\n' libssl-dev 2>/dev/null;
91	    pacman -Q mingw-w64-x86_64-openssl 2>/dev/null |
92	      sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')";;
93	MSYS*x86_64*)
94	    opensslver="$(pacman -Q openssl-devel 2>/dev/null |
95	      sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')";;
96	MINGW64*)
97	    opensslver="$(pacman -Q mingw-w64-x86_64-openssl 2>/dev/null |
98	      sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')";;
99	*)
100	    opensslver=1.0;;
101    esac
102fi
103if grep -q 'CentOS release 4' /etc/issue 2>/dev/null; then
104  opensslver=""
105fi
106echo "opensslver=$opensslver"
107
108case "$(uname)" in
109    FreeBSD*)
110	libssh2ver="$(freebsd_pkg_version libssh2 2>/dev/null)";;
111    Linux*)
112	libssh2ver="$(for p in openssh-devel libssh2-devel libssh-devel; do
113                rpm -q --qf '%{version}\n' $p 2>/dev/null |
114                  grep -v 'not installed';
115              done |
116              head -n1;
117              for p in libopenssh2 libssh2-1-dev libssh-dev; do
118                dpkg-query --show -f '${Version}\n' $p 2>/dev/null;
119              done | grep -v '^$';
120              pacman -Q mingw-w64-x86_64-libssh2 2>/dev/null |
121                sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')"
122	;;
123esac
124echo "libssh2ver=$libssh2ver"
125
126case "$(uname)" in
127    FreeBSD*)
128	perldevver="$(freebsd_pkg_version perl5 2>/dev/null)";;
129    Linux*)
130	perldevver="$(for p in perl; do
131                rpm -q --qf '%{version}\n' $p 2>/dev/null |
132                  grep -v 'not installed';
133              done |
134              head -n1;
135	      for p in libperl-dev; do
136	        dpkg-query --show -f '${Version}\n' $p 2>/dev/null;
137              done | grep -v '^$';
138              pacman -Q mingw-w64-x86_64-perl 2>/dev/null |
139                sed -n 's/^[^[:blank:]]*[[:blank:]]*//p')"
140	;;
141esac
142echo "perldevver=$perldevver"
143
144options=()
145options+=(--enable-developer)
146options+=(--enable-ipv6)
147options+=("--prefix=/usr/local/net-snmp-${branch_name}")
148options+=("--with-cflags=$cflags")
149options+=(--with-defaults)
150transports=()
151# Mib names can be found as follows:
152# (cd agent/mibgroup &&
153# git grep -lE 'void[[:blank:]]*init_.*\(void\)|config_require\(' |
154#  sed -n 's/\.h$//p')
155mibs=()
156case "$MODE" in
157    read-only)
158        ;;
159    *)
160        mibs+=(examples/data_set)
161        mibs+=(examples/delayed_instance)
162        mibs+=(examples/example)
163        mibs+=(examples/notification)
164        mibs+=(examples/scalar_int)
165        mibs+=(examples/ucdDemoPublic)
166        mibs+=(examples/watched)
167        mibs+=(smux)
168        ;;
169esac
170
171case "$(uname)" in
172  Linux*)
173      options+=(--enable-new-features)
174      case "$MODE" in
175          mini*|read-only)
176              ;;
177          *)
178              $is_5_7_or_above && mibs+=(deliver/deliverByNotify)
179              mibs+=(disman/event)
180              #mibs+=(disman/expression) - to do: figure out why this fails on Travis
181              mibs+=(disman/mteEventNotificationTable)
182              mibs+=(disman/mteEventTable)
183              mibs+=(disman/mteObjectsTable)
184              mibs+=(disman/mteTriggerBooleanTable)
185              mibs+=(disman/mteTriggerDeltaTable)
186              mibs+=(disman/mteTriggerExistenceTable)
187              mibs+=(disman/mteTriggerTable)
188              mibs+=(disman/mteTriggerThresholdTable)
189              mibs+=(disman/nslookup-mib)
190              mibs+=(disman/ping-mib)
191              mibs+=(disman/schedule)
192              mibs+=(disman/traceroute-mib)
193              mibs+=(etherlike-mib)
194              mibs+=(examples/netSnmpHostsTable)
195              mibs+=(hardware/cpu)
196              mibs+=(hardware/fsys)
197              mibs+=(hardware/memory)
198              mibs+=(host)
199              mibs+=(ip-forward-mib)
200              mibs+=(ip-mib/inetNetToMediaTable)
201              mibs+=(ip-mib/ipDefaultRouterTable)
202              mibs+=(ip-mib/ipv4InterfaceTable)
203              mibs+=(ip-mib/ipv6InterfaceTable)
204              mibs+=(ip-mib/ipv6ScopeZoneIndexTable)
205              mibs+=(mibII/mta_sendmail)
206              mibs+=(misc/ipfwacc)
207              mibs+=(sctp-mib)
208              mibs+=(snmp-notification-mib)
209              mibs+=(tcp-mib)
210              mibs+=(testhandler)
211              mibs+=(tunnel)
212              mibs+=(ucd-snmp/diskio)
213	      if [ -n "$libsensorsver" ]; then
214		  mibs+=(hardware/sensors)
215		  mibs+=(ucd-snmp/lmsensorsMib)
216	      fi
217              mibs+=(ucd-snmp/extensible)
218              mibs+=(udp-mib)
219	      mibs+=(rmon-mib)
220              ;;
221      esac
222      # Disable MySQL support because of the following Perl test failure on
223      # Travis:
224      # t/1.t .. Can't load '/home/travis/build/bvanassche/net-snmp/perl/TrapReceiver/../blib/arch/auto/NetSNMP/TrapReceiver/TrapReceiver.so' for module NetSNMP::TrapReceiver: /home/travis/build/bvanassche/net-snmp/apps/.libs/libnetsnmptrapd.so.35: undefined symbol: mysql_sqlstate at /usr/lib/x86_64-linux-gnu/perl/5.22/DynaLoader.pm line 187.
225      # at t/1.t line 16.
226      if false && [ -n "$libmysqlver" ]; then
227	  options+=(--with-mysql)
228      fi
229      if [ -n "$perldevver" ]; then
230	  options+=(--with-perl-modules)
231      else
232	  options+=(--disable-embedded-perl --without-perl-modules)
233      fi
234      if [ -n "$libatmver" ]; then
235	  transports+=(AAL5PVC)
236      fi
237      transports+=(IPX)
238      transports+=(STD)
239      $is_5_8_or_above && transports+=(UDPshared)
240      options+=("--with-default-snmp-version=2")
241      options+=("--with-systemd")
242      # Disabled modules because troublesome: Rmon ipfwchains/ipfwchains ucd-snmp/lmSensors
243    ;;
244  darwin*|Darwin*)
245      case "$MODE" in
246          mini*|read-only)
247              ;;
248          *)
249              mibs+=(disman/nslookup-mib)
250              mibs+=(host)
251              mibs+=(if-mib)
252              mibs+=(mibII/mta_sendmail)
253              mibs+=(misc/ipfwacc)
254              mibs+=(snmp-notification-mib)
255              mibs+=(tcp-mib)
256              mibs+=(ucd-snmp/diskio)
257              mibs+=(ucd-snmp/extensible)
258              mibs+=(udp-mib)
259              mibs+=(Rmon)
260              ;;
261      esac
262      if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
263          options+=("--with-openssl=$(brew --prefix openssl)")
264          # On Travis OS/X linking the Perl modules fails with "undefined symbol
265          # _BN_bin2bn" etc.
266          options+=(--disable-embedded-perl --without-perl-modules)
267      fi
268    ;;
269  FreeBSD*)
270      case "$MODE" in
271          mini*|read-only)
272              ;;
273          *)
274              mibs+=(disman/nslookup-mib)
275              mibs+=(host)
276              mibs+=(if-mib)
277              mibs+=(mibII/mta_sendmail)
278              mibs+=(misc/ipfwacc)
279              mibs+=(sctp-mib)
280              mibs+=(snmp-notification-mib)
281              mibs+=(tcp-mib)
282              mibs+=(ucd-snmp/diskio)
283              mibs+=(ucd-snmp/extensible)
284              mibs+=(udp-mib)
285              mibs+=(Rmon)
286              ;;
287      esac
288      options+=(--disable-embedded-perl --without-perl-modules)
289    ;;
290  CYGWIN*)
291      export ENV_SEPARATOR=":"
292      mibs+=(ucd-snmp/extensible)
293      mibs+=(winExtDLL)
294      options+=(--disable-embedded-perl --without-perl-modules)
295    ;;
296  MINGW*)
297      options+=(--disable-embedded-perl)
298      mibs+=(host)
299      mibs+=(snmp-notification-mib)
300      mibs+=(ucd-snmp/dlmod)
301      mibs+=(ucd-snmp/extensible)
302      mibs+=(winExtDLL)
303      options+=(--without-perl-modules)
304    ;;
305  MSYS*)
306      options+=(--disable-embedded-perl)
307      mibs+=(host)
308      mibs+=(snmp-notification-mib)
309      mibs+=(ucd-snmp/dlmod)
310      mibs+=(ucd-snmp/extensible)
311      mibs+=(winExtDLL)
312      options+=(--without-perl-modules)
313      # The config.guess script in the Net-SNMP source tree is too old to
314      # recognize the MSYS2 environment. Hence the explicit --build=... option.
315      # See also
316      # http://git.savannah.gnu.org/cgit/automake.git/tree/lib/config.guess.
317      options+=("--build=x86_64-pc-mingw32")
318    ;;
319  *)
320    echo "Unknown OS $(uname)."
321    ;;
322esac
323
324with_openssl=""
325for o in "${options[@]}"; do
326    if [ "${o#--with-openssl=}" != "$o" ]; then
327        with_openssl="${o#--with-openssl=}"
328    fi
329done
330if [ "$opensslver" = "" ]; then
331    options+=("--with-openssl=internal")
332    with_openssl="internal"
333else
334    if grep -rqw BIO_dgram_get_peer "$(ssl_include_path)" 2>/dev/null; then
335	transports+=(DTLSUDP TLSTCP)
336    fi
337    if [ "$MODE" != "read-only" ]; then
338	# these MIB modules do not support read-only
339	if [ -e "$(ssl_include_path)/dh.h" ]; then
340	    mibs+=(snmp-usm-dh-objects-mib)
341	fi
342	if [ -e "$(ssl_include_path)/ssl.h" ]; then
343	    mibs+=(tlstm-mib)
344	fi
345	mibs+=(tsm-mib)
346    fi
347fi
348if [ "$with_openssl" != "internal" ] && $is_5_8_or_above &&
349       [ -e "$(ssl_include_path)/aes.h" ] &&
350       [ -e "$(ssl_include_path)/evp.h" ]; then
351       options+=(--enable-blumenthal-aes)
352fi
353security_modules=(usm tsm)
354if [ -e /usr/include/krb5.h ]; then
355    security_modules+=(ksm)
356fi
357case "$(uname)" in
358    MSYS*|MINGW*)
359	# Do not enable Python support on MinGW32 nor for the MSYS build
360	# environment because the Python interpreter has been built on these
361	# environments with Visual C++. That compiler is incompatible with gcc.
362        ;;
363    Darwin*)
364	case "$(uname -r)" in
365	    11.*|12.*)
366		if python3 -c 'import setuptools' 1>/dev/null 2>&1; then
367		    options+=(--with-python-modules)
368		fi
369		;;
370	    *)
371		;;
372	esac
373	;;
374    *)
375	# Do not enable Python support for Cirrus CI because on Cirrus linking
376	# with Python fails as follows (this is probably a bug in Net-SNMP):
377	# /usr/bin/ld: /tmp/cirrus-ci-build/snmplib/.libs/libnetsnmp.a(snmp_client.o): relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
378	if python3 -c 'import setuptools' 1>/dev/null 2>&1 &&
379	       [ -z "$CIRRUS_CI" ]; then
380	    options+=(--with-python-modules)
381	fi
382    esac
383
384case "$MODE" in
385    disable-set)
386        options+=(--disable-set-support);;
387    mini)
388        options+=(--enable-mini-agent);;
389    minimalist)
390        options+=(--enable-minimalist);;
391    read-only)
392        options+=(--enable-read-only);;
393    regular|"")
394        ;;
395    *)
396        echo "Error: unknown build type $MODE"
397        exit 1;;
398esac
399
400[ "${libssh2ver#2}" != "${libssh2ver}" ] && transports+=(SSH)
401set -x
402./configure "${options[@]}" --with-transports="${transports[*]}" \
403            --with-security-modules="${security_modules[*]}"	 \
404	    --with-mib-modules="${mibs[*]}" "$@"
405