build: Put the note from the bottom of the old BUILD_SYSTEMS.txt somewhere useful
[samba.git] / source3 / wscript
1 #!/usr/bin/env python
2
3 srcdir = ".."
4
5 import sys, os
6 from optparse import SUPPRESS_HELP
7 sys.path.insert(0, srcdir + "/buildtools/wafsamba")
8 sys.path.insert(0, "source3")
9
10 from waflib import Options, Logs, Errors
11 import wafsamba
12 import build.charset
13 from wafsamba import samba_utils
14 from samba_utils import TO_LIST
15 import samba3
16 from waflib.Tools import bison
17
18 default_prefix = Options.default_prefix = '/usr/local/samba'
19
20 def options(opt):
21
22     opt.add_option('--with-static-modules',
23                    help=("Comma-separated list of names of modules to statically link in. "+
24                          "May include !module to disable 'module'. "+
25                          "Can be '!FORCED' to disable all non-required static only modules. "+
26                          "Can be '!DEFAULT' to disable all modules defaulting to a static build. "+
27                          "Can be 'ALL' to build all default shared modules static. "+
28                          "The most specific one wins, while the order is ignored "+
29                          "and --with-static-modules is evaluated before "+
30                          "--with-shared-modules"),
31                    action="store", dest='static_modules', default=None)
32     opt.add_option('--with-shared-modules',
33                    help=("Comma-separated list of names of modules to build shared. "+
34                          "May include !module to disable 'module'. "+
35                          "Can be '!FORCED' to disable all non-required shared only modules. "+
36                          "Can be '!DEFAULT' to disable all modules defaulting to a shared build. "+
37                          "Can be 'ALL' to build all default static modules shared. "+
38                          "The most specific one wins, while the order is ignored "+
39                          "and --with-static-modules is evaluated before "+
40                          "--with-shared-modules"),
41                    action="store", dest='shared_modules', default=None)
42
43 # Optional Libraries
44 # ------------------
45 #
46 # Most of the calls to opt.samba_add_onoff_option() implicitly
47 # or explicity use default=True
48 #
49 # To assist users and distributors to build Samba with the full feature
50 # set, the build system will abort if our dependent libraries and their
51 # header files are not found on the target system.  This will mean for
52 # example, that xattr, acl and ldap headers must be installed for the
53 # default build to complete.  The configure system will check for these
54 # headers, and the error message will indicate the option (such as
55 # --without-acl-support) that can be specified to skip this requirement.
56 #
57 # This will assist users and in particular distributors in building fully
58 # functional packages, while allowing those on systems truly without these
59 # facilities to continue to build Samba after careful consideration.
60 #
61 # It also ensures our container image generation in bootstrap/ is correct
62 # as otherwise a missing package there would just silently work
63
64     opt.samba_add_onoff_option('winbind')
65     opt.samba_add_onoff_option('ads')
66     opt.samba_add_onoff_option('ldap')
67     opt.samba_add_onoff_option('cups', with_name="enable", without_name="disable")
68     opt.samba_add_onoff_option('iprint', with_name="enable", without_name="disable")
69     opt.samba_add_onoff_option('pam')
70     opt.samba_add_onoff_option('quotas', default=None)
71     opt.samba_add_onoff_option('sendfile-support', default=None)
72     opt.samba_add_onoff_option('utmp')
73     opt.samba_add_onoff_option('avahi', with_name="enable", without_name="disable")
74     opt.samba_add_onoff_option('iconv')
75     opt.samba_add_onoff_option('acl-support')
76     opt.samba_add_onoff_option('dnsupdate')
77     opt.samba_add_onoff_option('syslog')
78     opt.samba_add_onoff_option('automount')
79     opt.samba_add_onoff_option('dmapi', default=None) # None means autodetection
80     opt.samba_add_onoff_option('fam', default=None) # None means autodetection
81     opt.samba_add_onoff_option('profiling-data', default=False)
82     opt.samba_add_onoff_option('libarchive', default=True)
83
84     opt.samba_add_onoff_option('cluster-support', default=False)
85
86     opt.samba_add_onoff_option('regedit', default=None)
87     opt.samba_add_onoff_option('winexe', default=None)
88
89     opt.samba_add_onoff_option('fake-kaserver',
90                           help=("Include AFS fake-kaserver support"), default=False)
91
92     opt.add_option('--with-libcephfs',
93                    help=("Directory under which libcephfs is installed"),
94                    action="store", dest='libcephfs_dir', default=None)
95
96     opt.samba_add_onoff_option('glusterfs', with_name="enable", without_name="disable", default=True)
97     opt.samba_add_onoff_option('cephfs', with_name="enable", without_name="disable", default=True)
98     opt.samba_add_onoff_option('snapper', with_name="enable", without_name="disable", default=True)
99
100     opt.add_option('--enable-vxfs',
101                   help=("enable support for VxFS (default=no)"),
102                   action="store_true", dest='enable_vxfs', default=False)
103
104     # default = None means autodetection
105     opt.samba_add_onoff_option('spotlight', with_name="enable", without_name="disable", default=None)
106
107 def configure(conf):
108     default_static_modules = []
109     default_shared_modules = []
110     required_static_modules = []
111     forced_static_modules = []
112     forced_shared_modules = []
113
114     if Options.options.developer:
115         conf.ADD_CFLAGS('-DDEVELOPER -DDEBUG_PASSWORD')
116         conf.env.developer = True
117
118     if sys.platform != 'openbsd5':
119         conf.ADD_LDFLAGS("-Wl,--export-dynamic", testflags=True)
120
121     # We crash without vfs_default
122     # and vfs_not_implemented provides helper function
123     # for other modules
124     required_static_modules.extend(TO_LIST('vfs_default vfs_not_implemented'))
125
126     conf.CHECK_HEADERS('netdb.h')
127     conf.CHECK_HEADERS('linux/falloc.h linux/ioctl.h')
128
129     conf.CHECK_FUNCS('getcwd fchown chmod fchmod mknod mknodat')
130     conf.CHECK_FUNCS('strtol strchr strupr chflags')
131     conf.CHECK_FUNCS('getrlimit fsync setpgid')
132     conf.CHECK_FUNCS('setsid glob strpbrk crypt16 getauthuid')
133     conf.CHECK_FUNCS('innetgr')
134     conf.CHECK_FUNCS('initgroups select poll rdchk getgrnam getgrent pathconf')
135     conf.CHECK_FUNCS('setpriv setgidx setuidx setgroups syscall sysconf')
136     conf.CHECK_FUNCS('atexit grantpt posix_openpt fallocate')
137     conf.CHECK_FUNCS('fseeko setluid')
138     conf.CHECK_FUNCS('getpwnam', headers='sys/types.h pwd.h')
139     conf.CHECK_FUNCS('fdopendir')
140     conf.CHECK_FUNCS('fstatat')
141     conf.CHECK_FUNCS('getpwent_r setenv clearenv strcasecmp fcvt fcvtl')
142     conf.CHECK_FUNCS('syslog vsyslog timegm setlocale')
143     conf.CHECK_FUNCS('lutimes futimes utimensat futimens')
144     conf.CHECK_FUNCS('mlock munlock mlockall munlockall')
145     conf.CHECK_FUNCS('memalign posix_memalign hstrerror')
146     conf.CHECK_FUNCS_IN('yp_get_default_domain', 'nsl')
147     conf.CHECK_FUNCS_IN('dn_expand _dn_expand __dn_expand', 'resolv')
148     conf.CHECK_FUNCS_IN('dn_expand', 'inet')
149     conf.CHECK_DECLS('readahead', reverse=True, headers='fcntl.h')
150
151     if conf.CHECK_CODE('''
152 #if defined(HAVE_UNISTD_H)
153 #include <unistd.h>
154 #endif
155 long ret = splice(0,0,1,0,400,SPLICE_F_MOVE);
156 ''',
157         'HAVE_LINUX_SPLICE',
158         headers='fcntl.h'):
159         conf.CHECK_DECLS('splice', reverse=True, headers='fcntl.h')
160
161     # Check for inotify support (Skip if we are SunOS)
162     #NOTE: illumos provides sys/inotify.h but is not an exact match for linux
163     host_os = sys.platform
164     if host_os.rfind('sunos') == -1:
165         conf.CHECK_HEADERS('sys/inotify.h')
166         if conf.env.HAVE_SYS_INOTIFY_H:
167            conf.DEFINE('HAVE_INOTIFY', 1)
168
169     # Check for kernel change notify support
170     conf.CHECK_CODE('''
171 #ifndef F_NOTIFY
172 #define F_NOTIFY 1026
173 #endif
174 main() {
175         exit(fcntl(open("/tmp", O_RDONLY), F_NOTIFY, 0) == -1 ?  1 : 0);
176 }''', 'HAVE_KERNEL_CHANGE_NOTIFY', addmain=False, execute=True,
177         headers='fcntl.h signal.h',
178         msg="Checking for kernel change notify support")
179
180     # Check for Linux kernel oplocks
181     conf.CHECK_CODE('''
182 #include <sys/types.h>
183 #include <fcntl.h>
184 #include <signal.h>
185 #ifndef F_GETLEASE
186 #define F_GETLEASE 1025
187 #endif
188 main() {
189         exit(fcntl(open("/tmp", O_RDONLY), F_GETLEASE, 0) == -1 ?  1 : 0);
190 }''', 'HAVE_KERNEL_OPLOCKS_LINUX', addmain=False, execute=True,
191         msg="Checking for Linux kernel oplocks")
192
193     # Check for kernel share modes
194     conf.CHECK_CODE('''
195 #include <sys/types.h>
196 #include <fcntl.h>
197 #include <signal.h>
198 #include <sys/file.h>
199 #ifndef LOCK_MAND
200 #define LOCK_MAND        32
201 #define LOCK_READ        64
202 #endif
203 main() {
204         exit(flock(open("/dev/null", O_RDWR), LOCK_MAND|LOCK_READ) != 0);
205 }''', 'HAVE_KERNEL_SHARE_MODES', addmain=False, execute=True,
206         msg="Checking for kernel share modes")
207
208     # check for fam libs
209     samba_fam_libs=None
210     check_for_fam=False
211     if Options.options.with_fam is None:
212         check_for_fam=True
213     elif Options.options.with_fam == True:
214         check_for_fam=True
215
216     if check_for_fam and conf.CHECK_HEADERS('fam.h'):
217         if conf.CHECK_FUNCS_IN('FAMOpen2', 'fam'):
218             samba_fam_libs='fam'
219         elif conf.CHECK_FUNCS_IN('FAMOpen2', 'fam C'):
220             samba_fam_libs='fam C'
221         conf.CHECK_TYPE('enum FAMCodes', headers='fam.h',
222             define='HAVE_FAM_H_FAMCODES_TYPEDEF',
223             msg='Checking whether enum FAMCodes is available')
224         conf.CHECK_FUNCS_IN('FAMNoExists', 'fam')
225
226     if samba_fam_libs is not None:
227         conf.DEFINE('SAMBA_FAM_LIBS', samba_fam_libs)
228         conf.DEFINE('HAVE_FAM', 1)
229     else:
230         if Options.options.with_fam == True:
231             conf.fatal('FAM support requested, but no suitable FAM library found')
232         elif check_for_fam:
233             Logs.warn('no suitable FAM library found')
234
235     # check for libarchive (tar command in smbclient)
236     # None means autodetect, True/False means enable/disable
237     conf.SET_TARGET_TYPE('archive', 'EMPTY')
238     if Options.options.with_libarchive is not False:
239         Logs.info("Checking for libarchive existence")
240         if conf.CHECK_HEADERS('archive.h') and conf.CHECK_LIB('archive', shlib=True):
241             conf.CHECK_FUNCS_IN('archive_read_support_filter_all archive_read_free', 'archive')
242         else:
243             conf.fatal("libarchive support not found. "
244                        "Try installing libarchive-dev or libarchive-devel. "
245                        "Otherwise, use --without-libarchive to "
246                        "build without libarchive support. "
247                        "libarchive support is required for the smbclient "
248                        "tar-file mode")
249     elif conf.CONFIG_GET('ENABLE_SELFTEST'):
250         raise Errors.WafError('libarchive library required for '
251                              '--enable-selftest')
252
253
254     # check for DMAPI libs
255     if Options.options.with_dmapi == False:
256         have_dmapi = False
257     else:
258         have_dmapi = True
259         Logs.info("Checking for DMAPI library existence")
260         samba_dmapi_lib = ''
261         if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dm'):
262             samba_dmapi_lib = 'dm'
263         else:
264             if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'jfsdm'):
265                 samba_dmapi_lib = 'jfsdm'
266             else:
267                 if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'dmapi'):
268                     samba_dmapi_lib = 'dmapi'
269                 else:
270                     if conf.CHECK_FUNCS_IN('dm_get_eventlist', 'xdsm'):
271                         samba_dmapi_lib = 'xdsm'
272         # only bother to test headers and compilation when a candidate
273         # library has been found
274         if samba_dmapi_lib == '':
275             have_dmapi = False
276             broken_dmapi = "no suitable DMAPI library found"
277
278         if have_dmapi:
279             conf.CHECK_HEADERS('sys/dmi.h xfs/dmapi.h sys/jfsdmapi.h sys/dmapi.h dmapi.h')
280             conf.CHECK_CODE('''
281 #include <time.h>      /* needed by Tru64 */
282 #include <sys/types.h> /* needed by AIX */
283 #ifdef HAVE_XFS_DMAPI_H
284 #include <xfs/dmapi.h>
285 #elif defined(HAVE_SYS_DMI_H)
286 #include <sys/dmi.h>
287 #elif defined(HAVE_SYS_JFSDMAPI_H)
288 #include <sys/jfsdmapi.h>
289 #elif defined(HAVE_SYS_DMAPI_H)
290 #include <sys/dmapi.h>
291 #elif defined(HAVE_DMAPI_H)
292 #include <dmapi.h>
293 #endif
294
295 /* This link test is designed to fail on IRI 6.4, but should
296  * succeed on Linux, IRIX 6.5 and AIX.
297  */
298 int main(int argc, char **argv)
299 {
300         char * version;
301         dm_eventset_t events;
302         /* This doesn't take an argument on IRIX 6.4. */
303         dm_init_service(&version);
304         /* IRIX 6.4 expects events to be a pointer. */
305         DMEV_ISSET(DM_EVENT_READ, events);
306
307         return 0;
308 }
309 ''',
310             'USEABLE_DMAPI_LIBRARY',
311             addmain=False,
312             execute=False,
313             lib=samba_dmapi_lib,
314             msg='Checking whether DMAPI lib '+samba_dmapi_lib+' can be used')
315             if not conf.CONFIG_SET('USEABLE_DMAPI_LIBRARY'):
316                 have_dmapi = False
317                 broken_dmapi = "no usable DMAPI library found"
318
319     if have_dmapi:
320         Logs.info("Building with DMAPI support.")
321         conf.env['dmapi_lib'] = samba_dmapi_lib
322         conf.DEFINE('USE_DMAPI', 1)
323     else:
324         if Options.options.with_dmapi == False:
325             Logs.info("Building without DMAPI support (--without-dmapi).")
326         elif Options.options.with_dmapi == True:
327             Logs.error("DMAPI support not available: " + broken_dmapi)
328             conf.fatal('DMAPI support requested but not found.');
329         else:
330             Logs.warn("Building without DMAPI support: " + broken_dmapi)
331         conf.env['dmapi_lib'] = ''
332
333     # Check for various members of the stat structure
334     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blocks', define='HAVE_STAT_ST_BLOCKS',
335                                 headers='sys/stat.h')
336     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_blksize', define='HAVE_STAT_ST_BLKSIZE',
337                                 headers='sys/stat.h')
338     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_flags', define='HAVE_STAT_ST_FLAGS',
339                                 headers='sys/types.h sys/stat.h unistd.h')
340
341     if conf.env.HAVE_BLKCNT_T:
342         conf.CHECK_CODE('''
343         static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 4)];''',
344                 'SIZEOF_BLKCNT_T_4',
345                 headers='replace.h sys/types.h sys/stat.h unistd.h',
346                 msg="Checking whether blkcnt_t is 32 bit")
347
348     # If sizeof is 4 it can't be 8
349     if conf.env.HAVE_BLKCNT_T:
350         if not conf.CONFIG_SET('SIZEOF_BLKCNT_T_4'):
351             conf.CHECK_CODE('''
352             static int test_array[1 - 2 * !(((long int)(sizeof(blkcnt_t))) <= 8)];''',
353                     'SIZEOF_BLKCNT_T_8',
354                     headers='replace.h sys/types.h sys/stat.h unistd.h',
355                     msg="Checking whether blkcnt_t is 64 bit")
356
357     # Check for POSIX capability support
358     conf.CHECK_FUNCS_IN('cap_get_proc', 'cap', headers='sys/capability.h')
359
360     if conf.env.HAVE_SYS_CAPABILITY_H:
361         conf.CHECK_CODE('''
362         cap_t cap;
363         cap_value_t vals[1];
364         if (!(cap = cap_get_proc())) exit(1);
365         vals[0] = CAP_CHOWN;
366         cap_set_flag(cap, CAP_INHERITABLE, 1, vals, CAP_CLEAR);
367         cap_set_proc(cap);''',
368                         'HAVE_POSIX_CAPABILITIES', execute=True, lib="cap",
369                         headers='sys/capability.h',
370                         msg="Checking whether POSIX capabilities are available")
371
372     conf.CHECK_CODE('int i;', 'BROKEN_NISPLUS_INCLUDE_FILES',
373                     headers='sys/types.h sys/acl.h rpcsvc/nis.h',
374                     msg="Checking for broken nisplus include files")
375
376     # Check if the compiler will optimize out functions
377     conf.CHECK_CODE('''
378 #include <sys/types.h>
379 size_t __unsafe_string_function_usage_here_size_t__(void);
380 #define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
381 static size_t push_string_check_fn(void *dest, const char *src, size_t dest_len) {
382         return 0;
383 }
384
385 #define push_string_check(dest, src, dest_len) \
386     (CHECK_STRING_SIZE(dest, dest_len) \
387     ? __unsafe_string_function_usage_here_size_t__()    \
388     : push_string_check_fn(dest, src, dest_len))
389
390 int main(int argc, char **argv) {
391     char outbuf[1024];
392     char *p = outbuf;
393     const char *foo = "bar";
394     p += 31 + push_string_check(p + 31, foo, sizeof(outbuf) - (p + 31 - outbuf));
395     return 0;
396 }''', 'HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS',
397             addmain=False,
398             add_headers=False,
399             msg="Checking if the compiler will optimize out functions")
400
401     # Check if the compiler supports the LL suffix on long long integers
402     # AIX needs this
403     conf.CHECK_CODE('long long i = 0x8000000000LL', 'COMPILER_SUPPORTS_LL',
404                     headers='stdio.h',
405                     msg="Checking for LL suffix on long long integers")
406
407     conf.CHECK_FUNCS('''
408 DNSServiceRegister
409 atexit
410 chflags
411 chmod
412 crypt16
413 devnm
414 dirfd
415 endmntent
416 execl
417 fchmod
418 fchown
419 fcvt
420 fcvtl
421 fseeko
422 fsync
423 futimens
424 futimes
425 getauthuid
426 getcwd
427 getgrent
428 getgrnam
429 getgrouplist
430 getgrset
431 getmntent
432 getpagesize
433 getpwanam
434 getpwent_r
435 getrlimit
436 glob
437 grantpt
438 hstrerror
439 initgroups
440 innetgr
441 llseek
442 lutimes
443 memalign
444 mknod
445 mlock
446 mlockall
447 munlock
448 munlockall
449 pathconf poll
450 posix_memalign
451 pread
452 pwrite
453 rdchk
454 select
455 setenv
456 setgidx
457 setgroups
458 setlocale
459 setluid
460 setmntent
461 setpgid
462 setpriv
463 setsid
464 setuidx
465 statvfs
466 strcasecmp
467 strchr
468 strpbrk
469 strsignal
470 strtol
471 strupr
472 sysconf
473 sysctl
474 sysctlbyname
475 syslog
476 timegm
477 utimensat
478 vsyslog
479 ''')
480
481     conf.CHECK_SAMBA3_CHARSET() # see build/charset.py
482
483     # FIXME: these should be tests for features, but the old build system just
484     # checks for OSes.
485     host_os = sys.platform
486     Logs.info("building on %s" % host_os)
487
488     # Python doesn't have case switches... :/
489     # FIXME: original was *linux* | gnu* | k*bsd*-gnu | kopensolaris*-gnu | *qnx*)
490     # the search for .rfind('gnu') covers gnu* and *-gnu is that too broad?
491
492     conf.SET_TARGET_TYPE('sunacl', 'EMPTY')
493     if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('qnx') > -1):
494         if host_os.rfind('linux') > -1:
495             conf.DEFINE('LINUX', '1')
496         elif host_os.rfind('qnx') > -1:
497             conf.DEFINE('QNX', '1')
498         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
499     elif (host_os.rfind('darwin') > -1):
500         conf.DEFINE('DARWINOS', 1)
501         conf.ADD_CFLAGS('-fno-common')
502         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
503     elif (host_os.rfind('freebsd') > -1):
504         conf.DEFINE('FREEBSD', 1)
505         if conf.CHECK_HEADERS('sunacl.h'):
506             conf.DEFINE('HAVE_FREEBSD_SUNACL_H', '1')
507             conf.CHECK_FUNCS_IN(['acl'], 'sunacl')
508         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
509     elif (host_os.rfind('irix') > -1):
510         conf.DEFINE('IRIX', 1)
511         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
512     elif (host_os.rfind('aix') > -1):
513         conf.DEFINE('AIX', 1)
514         conf.DEFINE('STAT_ST_BLOCKSIZE', 'DEV_BSIZE')
515     elif (host_os.rfind('hpux') > -1):
516         conf.DEFINE('HPUX', 1)
517         conf.DEFINE('STAT_ST_BLOCKSIZE', '8192')
518     elif (host_os.rfind('osf') > -1):
519         conf.DEFINE('OSF1', 1)
520         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
521
522     # FIXME: Add more checks here.
523     else:
524         conf.DEFINE('STAT_ST_BLOCKSIZE', '512')
525
526     if Options.options.with_acl_support:
527         if (host_os.rfind('hpux') > -1):
528                 Logs.info('Using HPUX ACLs')
529                 conf.DEFINE('HAVE_HPUX_ACLS',1)
530                 conf.DEFINE('POSIX_ACL_NEEDS_MASK',1)
531                 default_static_modules.extend(TO_LIST('vfs_hpuxacl'))
532         elif (host_os.rfind('aix') > -1):
533                 Logs.info('Using AIX ACLs')
534                 conf.DEFINE('HAVE_AIX_ACLS',1)
535                 default_static_modules.extend(TO_LIST('vfs_aixacl vfs_aixacl2'))
536         elif (host_os.rfind('darwin') > -1):
537             Logs.warn('ACLs on Darwin currently not supported')
538             conf.fatal("ACL support not available on Darwin/MacOS. "
539                        "Use --without-acl-support for building without "
540                        "ACL support. "
541                        "ACL support is required to change permissions "
542                        "from Windows clients.")
543         else:
544             conf.CHECK_FUNCS_IN(['acl_get_file'], 'acl')
545             if conf.CHECK_CODE('''
546 acl_t acl;
547 int entry_id;
548 acl_entry_t *entry_p;
549 return acl_get_entry(acl, entry_id, entry_p);
550 ''',
551                         'HAVE_POSIX_ACLS',
552                         headers='sys/types.h sys/acl.h', link=False,
553                         msg="Checking for POSIX ACL support") :
554                 conf.CHECK_CODE('''
555 acl_permset_t permset_d;
556 acl_perm_t perm;
557 return acl_get_perm_np(permset_d, perm);
558 ''',
559                         'HAVE_ACL_GET_PERM_NP',
560                         headers='sys/types.h sys/acl.h', link=True,
561                         msg="Checking whether acl_get_perm_np() is available")
562                 # source3/lib/sysacls.c calls posixacl_sys_acl_get_file()
563                 required_static_modules.extend(TO_LIST('vfs_posixacl'))
564                 conf.CHECK_VARIABLE('ACL_EVERYONE', headers='sys/acl.h')
565             elif conf.CHECK_FUNCS_IN(['facl'], 'sec'):
566                 Logs.info('Using solaris or UnixWare ACLs')
567                 conf.DEFINE('HAVE_SOLARIS_UNIXWARE_ACLS',1)
568                 default_static_modules.extend(TO_LIST('vfs_solarisacl'))
569             elif conf.CHECK_FUNCS_IN(['acl_get_fd'], 'pacl'):
570                 Logs.info('Using Tru64 ACLs')
571                 conf.DEFINE('HAVE_TRU64_ACLS',1)
572                 default_static_modules.extend(TO_LIST('vfs_tru64acl'))
573             else:
574                 conf.fatal("ACL support not found. Try installing libacl1-dev "
575                            "or libacl-devel.  "
576                            "Otherwise, use --without-acl-support to build "
577                            "without ACL support. "
578                            "ACL support is required to change permissions from "
579                            "Windows clients.")
580
581     if conf.CHECK_FUNCS('dirfd'):
582         conf.DEFINE('HAVE_DIRFD_DECL', 1)
583
584     conf.CHECK_CODE('struct statfs fsd; fsid_t fsid = fsd.f_fsid; return statfs(".", &fsd);',
585                     'HAVE_STATFS_F_FSID',
586                     msg="vfs_fileid checking for statfs() and struct statfs.f_fsid",
587                     headers='sys/types.h sys/statfs.h',
588                     execute=True)
589
590     if conf.CONFIG_SET('HAVE_FALLOCATE'):
591         conf.CHECK_CODE('''
592                 int ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 10);''',
593                 'HAVE_LINUX_FALLOCATE',
594                 msg="Checking whether the Linux 'fallocate' function is available",
595                 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
596         conf.CHECK_CODE('''
597                 int ret = fallocate(0, FALLOC_FL_PUNCH_HOLE, 0, 10);''',
598                 'HAVE_FALLOC_FL_PUNCH_HOLE',
599                 msg="Checking whether Linux 'fallocate' supports hole-punching",
600                 headers='unistd.h sys/types.h fcntl.h linux/falloc.h')
601
602     conf.CHECK_CODE('''
603             int ret = lseek(0, 0, SEEK_HOLE);
604             ret = lseek(0, 0, SEEK_DATA);''',
605             'HAVE_LSEEK_HOLE_DATA',
606             msg="Checking whether lseek supports hole/data seeking",
607             headers='unistd.h sys/types.h')
608
609     conf.CHECK_CODE('''
610                 ssize_t err = readahead(0,0,0x80000);''',
611                 'HAVE_LINUX_READAHEAD',
612                 msg="Checking whether Linux readahead is available",
613                 headers='unistd.h fcntl.h')
614     conf.CHECK_DECLS('readahead', headers='fcntl.h', always=True)
615
616     conf.CHECK_CODE('int fd = openat(AT_FDCWD, ".", O_RDONLY);',
617                 'HAVE_OPENAT',
618                 msg='Checking for openat',
619                 headers='fcntl.h')
620
621     conf.CHECK_CODE('''
622 struct msghdr msg;
623 union {
624         struct cmsghdr cm;
625         char control[CMSG_SPACE(sizeof(int))];
626 } control_un;
627 msg.msg_control = control_un.control;
628 msg.msg_controllen = sizeof(control_un.control);
629 ''',
630         'HAVE_STRUCT_MSGHDR_MSG_CONTROL',
631         msg='Checking if we can use msg_control for passing file descriptors',
632         headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
633     conf.CHECK_CODE('''
634 struct msghdr msg;
635 int fd;
636 msg.msg_accrights = (caddr_t) &fd;
637 msg.msg_accrightslen = sizeof(fd);
638 ''',
639         'HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS',
640         msg='Checking if we can use msg_accrights for passing file descriptors',
641         headers='sys/types.h stdlib.h stddef.h sys/socket.h sys/un.h')
642
643     if Options.options.with_winbind:
644         conf.env.build_winbind = True
645         conf.DEFINE('WITH_WINBIND', '1')
646
647     conf.find_program('awk', var='AWK')
648
649     conf.CHECK_HEADERS('asm/types.h')
650
651     conf.CHECK_CODE('dev_t dev; int i = major(dev); return 0', "HAVE_DEVICE_MAJOR_FN",
652                     headers='unistd.h sys/types.h',
653                     msg="Checking for major macro")
654
655     conf.CHECK_CODE('dev_t dev; int i = minor(dev); return 0', "HAVE_DEVICE_MINOR_FN",
656                     headers='unistd.h sys/types.h',
657                     msg="Checking for minor macro")
658
659     conf.CHECK_STRUCTURE_MEMBER('struct dirent', 'd_off',
660                                 headers='unistd.h sys/types.h dirent.h',
661                                 define='HAVE_DIRENT_D_OFF')
662
663     if (conf.CONFIG_SET('HAVE_YP_GET_DEFAULT_DOMAIN')):
664            conf.DEFINE('HAVE_NETGROUP', '1')
665
666     # Look for CUPS
667     if Options.options.with_cups:
668         conf.find_program('cups-config', var='CUPS_CONFIG')
669         if conf.env.CUPS_CONFIG:
670             # we would normally use --libs here, but cups-config incorrectly adds
671             # gssapi_krb5 and other libraries to its --libs output. That breaks the use
672             # of an in-tree heimdal kerberos
673             conf.CHECK_CFG(path=conf.env.CUPS_CONFIG, args="--cflags --ldflags",
674                            package="", uselib_store="CUPS")
675         conf.CHECK_HEADERS('cups/cups.h cups/language.h', lib='cups')
676         conf.CHECK_FUNCS_IN('httpConnect httpConnect2 httpConnectEncrypt', 'cups')
677         if conf.CONFIG_SET('HAVE_CUPS_CUPS_H') and conf.CONFIG_SET('HAVE_CUPS_LANGUAGE_H'):
678             conf.DEFINE('HAVE_CUPS', '1')
679         else:
680             conf.undefine('HAVE_CUPS')
681             conf.SET_TARGET_TYPE('cups', 'EMPTY')
682     else:
683         # define an empty subsystem for cups, to allow it to be used as an empty dependency
684         conf.SET_TARGET_TYPE('cups', 'EMPTY')
685
686     if Options.options.with_iprint:
687         if conf.CONFIG_SET('HAVE_CUPS'):
688             conf.DEFINE('HAVE_IPRINT', '1')
689         else:
690             Logs.warn("--enable-iprint=yes but cups support not sufficient")
691     if Options.options.with_syslog:
692         conf.DEFINE('WITH_SYSLOG', '1')
693     if Options.options.with_automount:
694         conf.DEFINE('WITH_AUTOMOUNT', '1')
695
696     # Check for LDAP
697     if Options.options.with_ldap:
698         conf.CHECK_HEADERS('ldap.h lber.h ldap_pvt.h')
699         conf.CHECK_TYPE('ber_tag_t', 'unsigned int', headers='ldap.h lber.h')
700         conf.CHECK_FUNCS_IN('ber_scanf ber_sockbuf_add_io', 'lber')
701         conf.CHECK_VARIABLE('LDAP_OPT_SOCKBUF', headers='ldap.h')
702
703         # if we LBER_OPT_LOG_PRINT_FN we can intercept ldap logging and print it out
704         # for the samba logs
705         conf.CHECK_VARIABLE('LBER_OPT_LOG_PRINT_FN',
706                             define='HAVE_LBER_LOG_PRINT_FN', headers='lber.h')
707
708         conf.CHECK_FUNCS_IN('ldap_init ldap_init_fd ldap_initialize ldap_set_rebind_proc', 'ldap')
709         conf.CHECK_FUNCS_IN('ldap_add_result_entry', 'ldap')
710
711         # Check if ldap_set_rebind_proc() takes three arguments
712         if conf.CHECK_CODE('ldap_set_rebind_proc(0, 0, 0)',
713                            'LDAP_SET_REBIND_PROC_ARGS',
714                            msg="Checking whether ldap_set_rebind_proc takes 3 arguments",
715                            headers='ldap.h lber.h', link=False):
716             conf.DEFINE('LDAP_SET_REBIND_PROC_ARGS', '3')
717         else:
718             conf.DEFINE('LDAP_SET_REBIND_PROC_ARGS', '2')
719
720         # last but not least, if ldap_init() exists, we want to use ldap
721         if conf.CONFIG_SET('HAVE_LDAP_INIT') and conf.CONFIG_SET('HAVE_LDAP_H'):
722             conf.DEFINE('HAVE_LDAP', '1')
723             conf.DEFINE('LDAP_DEPRECATED', '1')
724             conf.env['HAVE_LDAP'] = '1'
725             # if ber_sockbuf_add_io() and LDAP_OPT_SOCKBUF are available, we can add
726             # SASL wrapping hooks
727             if conf.CONFIG_SET('HAVE_BER_SOCKBUF_ADD_IO') and \
728                     conf.CONFIG_SET('HAVE_LDAP_OPT_SOCKBUF'):
729                 conf.DEFINE('HAVE_LDAP_SASL_WRAPPING', '1')
730         else:
731             conf.fatal("LDAP support not found. "
732                        "Try installing libldap2-dev or openldap-devel. "
733                        "Otherwise, use --without-ldap to build without "
734                        "LDAP support. "
735                        "LDAP support is required for the LDAP passdb backend, "
736                        "LDAP idmap backends and ADS. "
737                        "ADS support improves communication with "
738                        "Active Directory domain controllers.")
739     else:
740         conf.SET_TARGET_TYPE('ldap', 'EMPTY')
741         conf.SET_TARGET_TYPE('lber', 'EMPTY')
742
743     if Options.options.with_ads == False:
744         use_ads = False
745         use_ads_krb5 = False
746         use_ads_ldap = False
747     else:
748         use_ads = True
749         use_ads_krb5 = True
750         use_ads_ldap = True
751         if not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC_MD5') and \
752            not conf.CONFIG_SET('HAVE_ENCTYPE_ARCFOUR_HMAC'):
753             Logs.warn("arcfour-hmac-md5 encryption type not found in -lkrb5")
754             use_ads_krb5 = False
755         if not conf.CONFIG_SET('HAVE_KRB5_MK_REQ_EXTENDED'):
756             Logs.warn("krb5_mk_req_extended not found in -lkrb5")
757             use_ads_krb5 = False
758         if not conf.CONFIG_SET('HAVE_KRB5_GET_HOST_REALM'):
759             Logs.warn("krb5_get_host_realm not found in -lkrb5")
760             use_ads_krb5 = False
761         if not conf.CONFIG_SET('HAVE_KRB5_FREE_HOST_REALM'):
762             Logs.warn("krb5_free_host_realm not found in -lkrb5")
763             use_ads_krb5 = False
764         if not conf.CONFIG_SET('HAVE_KRB5_FWD_TGT_CREDS'):
765             Logs.warn("krb5_fwd_tgt_creds found in -lkrb5")
766             use_ads_krb5 = False
767         if not conf.CONFIG_SET('HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC'):
768             Logs.warn("krb5_get_init_creds_opt_alloc not found in -lkrb5")
769             use_ads_krb5 = False
770         if not conf.CONFIG_SET('KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT'):
771             Logs.warn("krb5_get_init_creds_opt_free was not found or was too old in -lkrb5")
772             use_ads_krb5 = False
773         if not conf.CONFIG_SET('HAVE_KRB5_GET_RENEWED_CREDS'):
774             Logs.warn("krb5_get_renewed_creds not found in -lkrb5")
775             use_ads_krb5 = False
776         if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM'):
777             Logs.warn("krb5_principal_compare_any_realm not found in -lkrb5")
778             use_ads_krb5 = False
779         if not conf.CONFIG_SET('HAVE_KRB5_C_STRING_TO_KEY') and \
780            not conf.CONFIG_SET('HAVE_KRB5_STRING_TO_KEY_SALT'):
781             Logs.warn("krb5_c_string_to_key not found in -lkrb5")
782             use_ads_krb5 = False
783         if not conf.CONFIG_SET('HAVE_KRB5_PRINCIPAL2SALT') and \
784            not conf.CONFIG_SET('HAVE_KRB5_GET_PW_SALT'):
785             Logs.warn("no CREATE_KEY_FUNCTIONS detected")
786             use_ads_krb5 = False
787         if not conf.CONFIG_SET('HAVE_KRB5_GET_PERMITTED_ENCTYPES') and \
788            not conf.CONFIG_SET('HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES'):
789             Logs.warn("no GET_ENCTYPES_FUNCTIONS detected")
790             use_ads_krb5 = False
791         if not conf.CONFIG_SET('HAVE_KRB5_KT_FREE_ENTRY') and \
792            not conf.CONFIG_SET('HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS'):
793             Logs.warn("no KT_FREE_FUNCTION detected")
794             use_ads_krb5 = False
795         if not conf.CONFIG_SET('HAVE_KRB5_C_VERIFY_CHECKSUM'):
796             Logs.warn("krb5_c_verify_checksum_compare not found in -lkrb5")
797             use_ads_krb5 = False
798
799         # We don't actually use
800         # gsskrb5_extract_authz_data_from_sec_context, but it is a
801         # clue that this Heimdal, which does the PAC processing we
802         # need on the standard gss_inquire_sec_context_by_oid
803         if not conf.CONFIG_SET('HAVE_GSS_GET_NAME_ATTRIBUTE') and \
804             not (conf.CONFIG_SET('HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT') and \
805                      conf.CONFIG_SET('HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID')):
806             Logs.warn("need either gss_get_name_attribute or gsskrb5_extract_authz_data_from_sec_context and gss_inquire_sec_context_by_oid in -lgssapi for PAC support")
807             use_ads_krb5 = False
808
809         if not conf.CONFIG_SET('HAVE_GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT'):
810             Logs.warn("need gss_krb5_export_lucid_sec_context for SPNEGO and gss_wrap support")
811             use_ads_krb5 = False
812
813         if use_ads_krb5:
814             conf.DEFINE('HAVE_KRB5', '1')
815             conf.env['HAVE_KRB5'] = '1'
816         else:
817             conf.undefine('HAVE_KRB5_H')
818             conf.undefine('HAVE_GSSAPI_H')
819             conf.undefine('HAVE_GSSAPI_GSSAPI_GENERIC_H')
820             conf.undefine('HAVE_GSSAPI_GSSAPI_H')
821             use_ads = False
822
823         if not conf.CONFIG_SET('HAVE_LDAP'):
824             use_ads = False
825             use_ads_ldap = False
826
827     if use_ads:
828         conf.DEFINE('WITH_ADS', '1')
829         conf.env['HAVE_ADS'] = '1'
830         Logs.info("Building with Active Directory support.")
831         # these have broken dependencies
832         forced_shared_modules.extend(TO_LIST('idmap_ad idmap_rfc2307'))
833     elif Options.options.with_ads == False:
834         Logs.info("Building without Active Directory support (--without-ads).")
835         if not Options.options.without_ad_dc:
836             conf.fatal("Building --without-ads requires also "
837                        "building --without-ad-dc.")
838     else:
839         if not use_ads_krb5:
840             Logs.warn("Active Directory support not available: krb5 libs don't have all required features")
841         if not use_ads_ldap:
842             Logs.warn("Active Directory support not available: LDAP support is not available.")
843         if Options.options.with_ads:
844             conf.fatal("Active Directory support not found. Use --without-ads "
845                        "for building without Active Directory support. "
846                        "ADS support improves communication with "
847                        "Active Directory domain controllers.")
848         else:
849             # this is the auto-mode case
850             Logs.warn("Building without Active Directory support.")
851
852
853     if Options.options.with_utmp:
854         conf.env.with_utmp = True
855         if not conf.CHECK_HEADERS('utmp.h'): conf.env.with_utmp = False
856         conf.CHECK_FUNCS('pututline pututxline updwtmp updwtmpx getutmpx getutxent')
857         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_name', headers='utmp.h',
858                                     define='HAVE_UT_UT_NAME')
859         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_user', headers='utmp.h',
860                                     define='HAVE_UT_UT_USER')
861         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_id', headers='utmp.h',
862                                     define='HAVE_UT_UT_ID')
863         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_host', headers='utmp.h',
864                                     define='HAVE_UT_UT_HOST')
865         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_time', headers='utmp.h',
866                                     define='HAVE_UT_UT_TIME')
867         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_tv', headers='utmp.h',
868                                     define='HAVE_UT_UT_TV')
869         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_type', headers='utmp.h',
870                                     define='HAVE_UT_UT_TYPE')
871         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_pid', headers='utmp.h',
872                                     define='HAVE_UT_UT_PID')
873         conf.CHECK_STRUCTURE_MEMBER('struct utmp', 'ut_exit.e_exit', headers='utmp.h',
874                                     define='HAVE_UT_UT_EXIT')
875         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_syslen', headers='utmpx.h',
876                                     define='HAVE_UX_UT_SYSLEN')
877         conf.CHECK_STRUCTURE_MEMBER('struct utmpx', 'ut_host', headers='utmpx.h',
878                                     define='HAVE_UX_UT_HOST')
879         conf.CHECK_CODE('struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);',
880                         'PUTUTLINE_RETURNS_UTMP', headers='utmp.h',
881                         msg="Checking whether pututline returns pointer")
882         conf.CHECK_SIZEOF(['((struct utmp *)NULL)->ut_line'], headers='utmp.h',
883                           define='SIZEOF_UTMP_UT_LINE', critical=False)
884         if not conf.CONFIG_SET('SIZEOF_UTMP_UT_LINE'):
885             conf.env.with_utmp = False
886         elif int(conf.env.SIZEOF_UTMP_UT_LINE) < 15:
887             conf.env.with_utmp = False
888         if conf.env.with_utmp:
889             conf.DEFINE('WITH_UTMP', 1)
890         else:
891             Logs.warn("--with-utmp but utmp support not sufficient")
892
893     if Options.options.with_avahi:
894         conf.env.with_avahi = True
895         if not conf.CHECK_HEADERS('avahi-common/watch.h avahi-client/client.h'): conf.env.with_avahi = False
896         if not conf.CHECK_FUNCS_IN('avahi_client_new', 'avahi-client'): conf.env.with_avahi = False
897         if not conf.CHECK_FUNCS_IN('avahi_strerror', 'avahi-common'): conf.env.with_avahi = False
898         if conf.env.with_avahi:
899             conf.DEFINE('WITH_AVAHI_SUPPORT', 1)
900     else:
901         conf.SET_TARGET_TYPE('avahi-common', 'EMPTY')
902         conf.SET_TARGET_TYPE('avahi-client', 'EMPTY')
903
904     if Options.options.with_iconv:
905         conf.env.with_iconv = True
906         if not conf.CHECK_FUNCS_IN('iconv_open', 'iconv', headers='iconv.h'):
907             conf.env.with_iconv = False
908         if conf.env.with_iconv:
909             conf.DEFINE('HAVE_ICONV', 1)
910
911     if Options.options.with_pam:
912         use_pam=True
913         conf.CHECK_HEADERS('security/pam_appl.h pam/pam_appl.h')
914         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_APPL_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_APPL_H'):
915             Logs.warn("--with-pam=yes but pam_appl.h not found")
916             use_pam=False
917         conf.CHECK_FUNCS_IN('pam_get_data', 'pam')
918         conf.CHECK_HEADERS('security/pam_modules.h pam/pam_modules.h')
919         if not conf.CONFIG_SET('HAVE_SECURITY_PAM_MODULES_H') and not conf.CONFIG_SET('HAVE_PAM_PAM_MODULES_H'):
920             Logs.warn("--with-pam=yes but pam_modules.h not found")
921             use_pam=False
922         conf.CHECK_HEADERS('security/pam_ext.h security/_pam_macros.h')
923         conf.CHECK_HEADERS('pam/pam_ext.h pam/_pam_macros.h')
924         conf.CHECK_FUNCS_IN('pam_vsyslog', 'pam')
925         conf.CHECK_CODE('''
926 #if defined(HAVE_SECURITY_PAM_APPL_H)
927 #include <security/pam_appl.h>
928 #elif defined(HAVE_PAM_PAM_APPL_H)
929 #include <pam/pam_appl.h>
930 #endif
931 pam_set_item(0, PAM_RHOST, 0);
932 ''',
933             'HAVE_PAM_RHOST',
934             lib='pam',
935             msg="Checking whether PAM_RHOST is available");
936         conf.CHECK_CODE('''
937 #if defined(HAVE_SECURITY_PAM_APPL_H)
938 #include <security/pam_appl.h>
939 #elif defined(HAVE_PAM_PAM_APPL_H)
940 #include <pam/pam_appl.h>
941 #endif
942 pam_set_item(0, PAM_TTY, 0);
943 ''',
944             'HAVE_PAM_TTY',
945             lib='pam',
946             msg="Checking whether PAM_TTY is available");
947         conf.CHECK_CODE('''
948 #if (!defined(LINUX))
949
950 #define PAM_EXTERN extern
951 #if defined(HAVE_SECURITY_PAM_APPL_H)
952 #include <security/pam_appl.h>
953 #elif defined(HAVE_PAM_PAM_APPL_H)
954 #include <pam/pam_appl.h>
955 #endif
956
957 #endif
958
959 #if defined(HAVE_SECURITY_PAM_MODULES_H)
960 #include <security/pam_modules.h>
961 #elif defined(HAVE_PAM_PAM_MODULES_H)
962 #include <pam/pam_modules.h>
963 #endif
964
965 #if defined(HAVE_SECURITY__PAM_MACROS_H)
966 #include <security/_pam_macros.h>
967 #elif defined(HAVE_PAM__PAM_MACROS_H)
968 #include <pam/_pam_macros.h>
969 #endif
970
971 #ifdef HAVE_SECURITY_PAM_EXT_H
972 #include <security/pam_ext.h>
973 #endif
974
975 int i; i = PAM_RADIO_TYPE;
976 ''',
977             'HAVE_PAM_RADIO_TYPE',
978             lib='pam',
979             msg="Checking whether PAM_RADIO_TYPE is available");
980         if use_pam:
981             conf.DEFINE('WITH_PAM', 1)
982             conf.DEFINE('WITH_PAM_MODULES', 1)
983         else:
984             conf.fatal("PAM support is enabled but prerequisite libraries "
985                        "or headers not found. Use --without-pam to disable "
986                        "PAM support.");
987
988     seteuid = False
989
990 #
991 # Ensure we select the correct set of system calls on Linux.
992 #
993     if (host_os.rfind('linux') > -1):
994         conf.CHECK_CODE('''
995 #if defined(HAVE_UNISTD_H)
996 #include <unistd.h>
997 #endif
998 #include <stdlib.h>
999 #include <stdio.h>
1000 #include <sys/types.h>
1001 #include <errno.h>
1002
1003 #ifdef HAVE_SYS_PRIV_H
1004 #include <sys/priv.h>
1005 #endif
1006 #ifdef HAVE_SYS_ID_H
1007 #include <sys/id.h>
1008 #endif
1009
1010 #if defined(HAVE_SYSCALL_H)
1011 #include <syscall.h>
1012 #endif
1013
1014 #if defined(HAVE_SYS_SYSCALL_H)
1015 #include <sys/syscall.h>
1016 #endif
1017
1018 syscall(SYS_setresuid32, -1, -1, -1);
1019 syscall(SYS_setresgid32, -1, -1, -1);
1020 syscall(SYS_setreuid32, -1, -1);
1021 syscall(SYS_setregid32, -1, -1);
1022 syscall(SYS_setuid32, -1);
1023 syscall(SYS_setgid32, -1);
1024 syscall(SYS_setgroups32, 0, NULL);
1025 ''',
1026             'USE_LINUX_32BIT_SYSCALLS',
1027             msg="Checking whether Linux should use 32-bit credential calls");
1028
1029         if (conf.CONFIG_SET('USE_LINUX_32BIT_SYSCALLS')):
1030             seteuid = conf.CHECK_CODE('''
1031                                 #define AUTOCONF_TEST 1
1032                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1033                                 #define USE_LINUX_32BIT_SYSCALLS 1
1034                                 #include "../lib/util/setid.c"
1035                                 #include "./lib/util_sec.c"
1036                                 ''',
1037                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1038                                 addmain=False,
1039                                 execute=True,
1040                                 msg="Checking whether we can use Linux thread-specific credentials with 32-bit system calls")
1041         else:
1042             seteuid = conf.CHECK_CODE('''
1043                                 #define AUTOCONF_TEST 1
1044                                 #define HAVE_LINUX_THREAD_CREDENTIALS 1
1045                                 #include "../lib/util/setid.c"
1046                                 #include "./lib/util_sec.c"
1047                                 ''',
1048                                 'HAVE_LINUX_THREAD_CREDENTIALS',
1049                                 addmain=False,
1050                                 execute=True,
1051                                 msg="Checking whether we can use Linux thread-specific credentials")
1052     if not seteuid:
1053         seteuid = conf.CHECK_CODE('''
1054                                 #define AUTOCONF_TEST 1
1055                                 #define USE_SETREUID 1
1056                                 #include "../lib/util/setid.c"
1057                                 #include "./lib/util_sec.c"
1058                                 ''',
1059                                 'USE_SETREUID',
1060                                 addmain=False,
1061                                 execute=True,
1062                                 msg="Checking whether setreuid is available")
1063     if not seteuid:
1064         seteuid = conf.CHECK_CODE('''
1065                                 #define AUTOCONF_TEST 1
1066                                 #define USE_SETRESUID 1
1067                                 #include "../lib/util/setid.c"
1068                                 #include "./lib/util_sec.c"
1069                                 ''',
1070                                 'USE_SETRESUID',
1071                                 addmain=False,
1072                                 execute=True,
1073                                 msg="Checking whether setresuid is available")
1074     if not seteuid:
1075         seteuid = conf.CHECK_CODE('''
1076                                 #define AUTOCONF_TEST 1
1077                                 #define USE_SETEUID 1
1078                                 #include "../lib/util/setid.c"
1079                                 #include "./lib/util_sec.c"
1080                                 ''',
1081                                 'USE_SETEUID',
1082                                 addmain=False,
1083                                 execute=True,
1084                                 msg="Checking whether seteuid is available")
1085     if not seteuid:
1086         seteuid = conf.CHECK_CODE('''
1087                                 #define AUTOCONF_TEST 1
1088                                 #define USE_SETUIDX 1
1089                                 #include "../lib/util/setid.c"
1090                                 #include "./lib/util_sec.c"
1091                                 ''',
1092                                 'USE_SETUIDX',
1093                                 addmain=False,
1094                                 execute=True,
1095                                 mandatory=True,
1096                                 msg="Checking whether setuidx is available")
1097     if Options.options.with_dnsupdate:
1098         if not conf.CONFIG_SET('HAVE_KRB5'):
1099             Logs.warn("--with-dnsupdate=yes but gssapi support not sufficient")
1100         else:
1101             conf.DEFINE('WITH_DNS_UPDATES', 1)
1102     # valgrind.h or valgrind/valgrind.h is checked in lib/replace/wscript
1103     if Options.options.developer:
1104         if conf.CONFIG_SET('HAVE_VALGRIND_H') or conf.CONFIG_SET('HAVE_VALGRIND_VALGRIND_H'):
1105             conf.DEFINE('VALGRIND', '1')
1106
1107     if conf.CHECK_CODE('''
1108 #include <bits/sockaddr.h>
1109 #include <linux/netlink.h>
1110 ''',
1111                 'HAVE_LINUX_NETLINK_H',
1112                 msg="Checking whether Linux netlink is available"):
1113
1114         conf.CHECK_CODE('''
1115 #include <bits/sockaddr.h>
1116 #include <linux/netlink.h>
1117 #include <linux/rtnetlink.h>
1118 ''',
1119                 'HAVE_LINUX_RTNETLINK_H',
1120                 msg='Checking whether Linux rtnetlink is available')
1121
1122     conf.CHECK_CODE('''
1123 #include "../tests/fcntl_lock.c"
1124 ''',
1125                 'HAVE_FCNTL_LOCK',
1126                 addmain=False,
1127                 execute=True,
1128                 msg='Checking whether fcntl locking is available')
1129
1130     conf.CHECK_CODE('''
1131 #include <unistd.h>
1132 #include <sys/types.h>
1133 #include <sys/stat.h>
1134 #include <fcntl.h>
1135 #include <errno.h>
1136
1137 #define DATA "ofdtest.fcntl"
1138
1139 int main() {
1140         struct flock lck = {
1141            .l_whence = SEEK_SET,
1142            .l_type = F_WRLCK,
1143            .l_start = 0,
1144            .l_len = 1,
1145            .l_pid = 0,
1146         };
1147         int ret;
1148         int fd1;
1149         int fd2;
1150         char *testdir = getenv("TESTDIR");
1151
1152         if (testdir) {
1153            if (chdir(testdir) != 0) {
1154               goto err;
1155            }
1156         }
1157
1158         unlink(DATA);
1159         fd1 = open(DATA, O_RDWR|O_CREAT|O_EXCL, 0600);
1160         fd2 = open(DATA, O_RDWR);
1161         if (fd1 == -1 || fd2 == -1) {
1162            goto err;
1163         }
1164         ret = fcntl(fd1,F_OFD_SETLKW,&lck);
1165         if (ret == -1) {
1166           goto err;
1167         }
1168         ret = fcntl(fd2,F_OFD_SETLK,&lck);
1169         if (ret != -1) {
1170           goto err;
1171         }
1172         if (errno != EAGAIN) {
1173           goto err;
1174         }
1175         ret = fcntl(fd2,F_OFD_GETLK,&lck);
1176         if (ret == -1) {
1177           goto err;
1178         }
1179         unlink(DATA);
1180         exit(0);
1181 err:
1182         unlink(DATA);
1183         exit(1);
1184 }''',
1185             'HAVE_OFD_LOCKS',
1186             addmain=False,
1187             execute=True,
1188             msg="Checking whether fcntl lock supports open file description locks")
1189
1190     conf.CHECK_CODE('''
1191 #include <fcntl.h>
1192 #include <unistd.h>
1193 #include <stdlib.h>
1194 #include <sys/socket.h>
1195
1196 int main(void)
1197 {
1198         int sockfd, ret;
1199         struct f_owner_ex owner, get_owner;
1200
1201         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
1202         if (sockfd == -1) {
1203             goto err;
1204         }
1205
1206         owner.type = F_OWNER_PID;
1207         owner.pid = getpid();
1208
1209         ret = fcntl(sockfd, F_SETOWN_EX, &owner);
1210         if (ret == -1) {
1211             goto err;
1212         }
1213
1214         ret = fcntl(sockfd, F_GETOWN_EX, &get_owner);
1215         if (ret == -1) {
1216             goto err;
1217         }
1218
1219         if (get_owner.type != F_OWNER_PID) {
1220             goto err;
1221         }
1222
1223         if (get_owner.pid != getpid()) {
1224             goto err;
1225         }
1226
1227         close(sockfd);
1228         exit(0);
1229 err:
1230         close(sockfd);
1231         exit(1);
1232 }''',
1233             'HAVE_F_OWNER_EX',
1234             addmain=False,
1235             execute=True,
1236             msg="Checking whether fcntl supports flags to send direct I/O availability signals")
1237
1238     conf.CHECK_CODE('''
1239 #include <fcntl.h>
1240 #include <unistd.h>
1241 #include <stdlib.h>
1242 #include <stdint.h>
1243
1244 #define DATA "hinttest.fcntl"
1245
1246 int main(void)
1247 {
1248         uint64_t *hint, get_hint;
1249         int fd;
1250
1251         fd = open(DATA, O_RDONLY | O_CREAT | O_EXCL);
1252         if (fd == -1) {
1253             goto err;
1254         }
1255
1256         *hint = RWH_WRITE_LIFE_SHORT;
1257         int ret = fcntl(fd, F_SET_RW_HINT, hint);
1258         if (ret == -1) {
1259             goto err;
1260         }
1261
1262         ret = fcntl(fd, F_GET_RW_HINT, &get_hint);
1263         if (ret == -1) {
1264             goto err;
1265         }
1266
1267         if (get_hint != RWH_WRITE_LIFE_SHORT) {
1268             goto err;
1269         }
1270
1271         *hint = RWH_WRITE_LIFE_EXTREME;
1272         ret = fcntl(fd, F_SET_FILE_RW_HINT, hint);
1273         if (ret == -1) {
1274             goto err;
1275         }
1276
1277         ret = fcntl(fd, F_GET_FILE_RW_HINT, &get_hint);
1278         if (ret == -1) {
1279             goto err;
1280         }
1281
1282         if (get_hint != RWH_WRITE_LIFE_EXTREME) {
1283             goto err;
1284         }
1285
1286         close(fd);
1287         unlink(DATA);
1288         exit(0);
1289 err:
1290         close(fd);
1291         unlink(DATA);
1292         exit(1);
1293 }''',
1294             'HAVE_RW_HINTS',
1295             addmain=False,
1296             execute=True,
1297             msg="Checking whether fcntl supports setting/geting hints")
1298
1299     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec',
1300                                 define='HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') # Linux, Solaris
1301     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimensec',
1302                                 define='HAVE_STRUCT_STAT_ST_MTIMENSEC') # BSD, if defined _POSIX_SOURCE
1303     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtimespec.tv_nsec',
1304                                 define='HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') # BSD, if not defined _POSIX_SOURCE
1305     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtime_n',
1306                                 define='HAVE_STRUCT_STAT_ST_MTIME_N') # AIX
1307     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_umtime',
1308                                 define='HAVE_STRUCT_STAT_ST_UMTIME') # Tru64
1309     if conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC') or \
1310        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMENSEC') or \
1311        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC') or \
1312        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_MTIME_N') or \
1313        conf.CONFIG_SET('HAVE_STRUCT_STAT_ST_UMTIME'):
1314         conf.DEFINE('HAVE_STAT_HIRES_TIMESTAMPS', '1')
1315
1316     # recent FreeBSD, NetBSD have creation timestamps called birthtime:
1317     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtime',
1318                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIME')
1319     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimespec.tv_nsec',
1320                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC')
1321     conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_birthtimensec',
1322                                 define='HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC')
1323
1324     conf.CHECK_CODE('''
1325 ssize_t err = posix_fadvise(0,0,0x80000,POSIX_FADV_WILLNEED);
1326 ''',
1327                 'HAVE_POSIX_FADVISE',
1328                 msg='Checking whether posix_fadvise is available',
1329                 headers='unistd.h fcntl.h')
1330
1331     for v in ['_SC_NGROUPS_MAX', '_SC_NPROC_ONLN', '_SC_NPROCESSORS_ONLN', '_SC_PAGESIZE' ]:
1332         conf.CHECK_CODE('''
1333                         #include <unistd.h>
1334                         return sysconf(%s) == -1 ? 1 : 0;
1335                         ''' % v,
1336                         'SYSCONF%s' % v,
1337                         msg='Checking whether sysconf(%s) is available' % v)
1338
1339     conf.CHECK_CODE('''
1340 #include <sys/syscall.h>
1341 #include <unistd.h>
1342 syscall(SYS_initgroups, 16, NULL, NULL, 0);
1343                     ''',
1344                     'HAVE_DARWIN_INITGROUPS',
1345                     msg='Checking whether to use the Darwin-specific initgroups system call')
1346
1347     conf.CHECK_CODE('''struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));''',
1348                     'HAVE_UTIMBUF',
1349                     headers='sys/types.h utime.h',
1350                     msg='Checking whether struct utimbuf is available')
1351
1352     if conf.CHECK_CODE('''struct sigevent s;''',
1353                     'HAVE_STRUCT_SIGEVENT',
1354                     headers='sys/types.h stdlib.h stddef.h signal.h',
1355                     msg='Checking whether we have the struct sigevent'):
1356         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sival_ptr',
1357                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIVAL_PTR',
1358                                     headers='signal.h');
1359         conf.CHECK_STRUCTURE_MEMBER('struct sigevent', 'sigev_value.sigval_ptr',
1360                                     define='HAVE_STRUCT_SIGEVENT_SIGEV_VALUE_SIGVAL_PTR',
1361                                     headers='signal.h');
1362
1363     if os.path.exists('/proc/sys/kernel/core_pattern'):
1364         conf.DEFINE('HAVE_SYS_KERNEL_PROC_CORE_PATTERN', '1')
1365
1366     if conf.CHECK_CODE('''
1367 #include <time.h>
1368 main() {
1369         struct tm *tm;
1370         if (sizeof(time_t) == 8) {
1371                 time_t max_time = 0x7fffffffffffffffll;
1372                 tm = gmtime(&max_time);
1373                 /* This should fail with 32-bit tm_year. */
1374                 if (tm == NULL) {
1375                         /* Max time_t that works with 32-bit int tm_year in struct tm. */
1376                         max_time = 67768036191676799ll;
1377                         tm = gmtime(&max_time);
1378                         if (tm) {
1379                                 exit(0);
1380                         }
1381                 }
1382         }
1383         exit(1);
1384 }''',
1385         '__TIME_T_MAX',
1386         addmain=False,
1387         execute=True,
1388         msg="Checking for the maximum value of the 'time_t' type"):
1389             conf.DEFINE('TIME_T_MAX', '67768036191676799ll')
1390
1391     conf.CHECK_CODE('''
1392 #if defined(HAVE_UNISTD_H)
1393 #include <unistd.h>
1394 #endif
1395 #include <sys/types.h>
1396 #if defined(HAVE_SYS_SYSMACROS_H)
1397 #include <sys/sysmacros.h>
1398 #endif
1399 main() { dev_t dev = makedev(1,2); return 0; }
1400 ''',
1401         'HAVE_MAKEDEV',
1402         addmain=False,
1403         msg='Checking whether the macro for makedev is available')
1404
1405     conf.CHECK_CODE('''
1406 #include <stdio.h>
1407 #include <limits.h>
1408 #include <signal.h>
1409
1410 void exit_on_core(int ignored) {
1411         exit(1);
1412 }
1413
1414 main() {
1415         char *newpath;
1416         signal(SIGSEGV, exit_on_core);
1417         newpath = realpath("/tmp", NULL);
1418         exit((newpath != NULL) ? 0 : 1);
1419 }
1420 ''',
1421         'REALPATH_TAKES_NULL',
1422         addmain=False,
1423         execute=True,
1424         msg='Checking whether the realpath function allows a NULL argument')
1425
1426     conf.CHECK_CODE('''#include "../tests/ftruncate.c"''',
1427                     'HAVE_FTRUNCATE_EXTEND',
1428                     msg='Checking for ftruncate extend',
1429                     addmain=False,
1430                     execute=True)
1431
1432     conf.SET_TARGET_TYPE('sendfile', 'EMPTY')
1433     conf.CHECK_LIB('sendfile')
1434     if not Options.options.with_sendfile_support == False:
1435         if (host_os.rfind('linux') > -1) or (host_os.rfind('gnu') > -1) or (host_os.rfind('k*bsd*-gnu') > -1) or (host_os.rfind('kopensolaris*-gnu') > -1):
1436             conf.CHECK_CODE('''
1437                             int tofd, fromfd;
1438                             off_t offset;
1439                             size_t total;
1440                             ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
1441                             ''',
1442                             '_HAVE_SENDFILE',
1443                             headers='sys/sendfile.h',
1444                             msg='Checking for linux sendfile support')
1445
1446             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1447                 conf.DEFINE('HAVE_SENDFILE', '1')
1448                 conf.DEFINE('LINUX_SENDFILE_API', '1')
1449         elif (host_os.rfind('freebsd') > -1) or (host_os.rfind('dragonfly') > -1):
1450             conf.CHECK_CODE('''
1451                             #include <sys/types.h>
1452                             #include <unistd.h>
1453                             #include <sys/socket.h>
1454                             #include <sys/uio.h>
1455                             int fromfd, tofd, ret, total=0;
1456                             off_t offset, nwritten;
1457                             struct sf_hdtr hdr;
1458                             struct iovec hdtrl;
1459                             hdr.headers = &hdtrl;
1460                             hdr.hdr_cnt = 1;
1461                             hdr.trailers = NULL;
1462                             hdr.trl_cnt = 0;
1463                             hdtrl.iov_base = NULL;
1464                             hdtrl.iov_len = 0;
1465                             ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0)
1466                             ''',
1467                             '_HAVE_SENDFILE',
1468                             msg='Checking for freebsd sendfile support')
1469             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1470                 conf.DEFINE('HAVE_SENDFILE', '1')
1471                 conf.DEFINE('FREEBSD_SENDFILE_API', '1')
1472         elif (host_os.rfind('darwin') > -1):
1473             conf.CHECK_CODE('''
1474                             #include <sys/types.h>
1475                             #include <sys/socket.h>
1476                             #include <sys/uio.h>
1477                             int fromfd, tofd, ret;
1478                             off_t offset, nwritten;
1479                             struct sf_hdtr hdr;
1480                             struct iovec hdtrl;
1481                             hdr.headers = &hdtrl;
1482                             hdr.hdr_cnt = 1;
1483                             hdr.trailers = (void *)0;
1484                             hdr.trl_cnt = 0;
1485                             hdtrl.iov_base = (void *)0;
1486                             hdtrl.iov_len = 0;
1487                             ret = sendfile(fromfd, tofd, offset, &nwritten, &hdr, 0);
1488                             ''',
1489                             '_HAVE_SENDFILE',
1490                             msg='Checking for darwin sendfile support')
1491             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1492                 conf.DEFINE('HAVE_SENDFILE', '1')
1493                 conf.DEFINE('DARWIN_SENDFILE_API', '1')
1494         elif (host_os.rfind('hpux') > -1) or (host_os.rfind('osf') > -1):
1495             conf.CHECK_CODE('''
1496                             #include <sys/socket.h>
1497                             #include <sys/uio.h>
1498                             int fromfd, tofd;
1499                             size_t total=0;
1500                             struct iovec hdtrl[2];
1501                             ssize_t nwritten;
1502                             off_t offset;
1503                             hdtrl[0].iov_base = 0;
1504                             hdtrl[0].iov_len = 0;
1505                             nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0);
1506                             ''',
1507                             '_HAVE_SENDFILE',
1508                             msg='Checking for osf/hpux sendfile support')
1509             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1510                 conf.DEFINE('HAVE_SENDFILE', '1')
1511                 conf.DEFINE('HPUX_SENDFILE_API', '1')
1512         elif (host_os.rfind('sunos') > -1):
1513             conf.CHECK_FUNCS_IN('sendfilev', 'sendfile')
1514             conf.CHECK_CODE('''
1515                             #include <sys/sendfile.h>,
1516                             int sfvcnt;
1517                             size_t xferred;
1518                             struct sendfilevec vec[2];
1519                             ssize_t nwritten;
1520                             int tofd;
1521                             sfvcnt = 2;
1522                             vec[0].sfv_fd = SFV_FD_SELF;
1523                             vec[0].sfv_flag = 0;
1524                             vec[0].sfv_off = 0;
1525                             vec[0].sfv_len = 0;
1526                             vec[1].sfv_fd = 0;
1527                             vec[1].sfv_flag = 0;
1528                             vec[1].sfv_off = 0;
1529                             vec[1].sfv_len = 0;
1530                             nwritten = sendfilev(tofd, vec, sfvcnt, &xferred);
1531                             ''',
1532                             '_HAVE_SENDFILEV',
1533                             msg='Checking for solaris sendfilev support',
1534                             lib='sendfile')
1535             if conf.CONFIG_SET('_HAVE_SENDFILEV'):
1536                 conf.DEFINE('HAVE_SENDFILEV', '1')
1537                 conf.DEFINE('SOLARIS_SENDFILE_API', '1')
1538         elif (host_os.rfind('aix') > -1):
1539             conf.CHECK_CODE('''
1540                             #include <sys/socket.h>
1541                             int fromfd, tofd;
1542                             size_t total=0;
1543                             struct sf_parms hdtrl;
1544                             ssize_t nwritten;
1545                             hdtrl.header_data = 0;
1546                             hdtrl.header_length = 0;
1547                             hdtrl.file_descriptor = fromfd;
1548                             hdtrl.file_offset = 0;
1549                             hdtrl.file_bytes = 0;
1550                             hdtrl.trailer_data = 0;
1551                             hdtrl.trailer_length = 0;
1552                             nwritten = send_file(&tofd, &hdtrl, 0);
1553                             ''',
1554                             '_HAVE_SENDFILE',
1555                             msg='Checking for AIX send_file support')
1556             if conf.CONFIG_SET('_HAVE_SENDFILE'):
1557                 conf.DEFINE('HAVE_SENDFILE', '1')
1558                 conf.DEFINE('AIX_SENDFILE_API', '1')
1559
1560     if Options.options.with_sendfile_support == True and not conf.CONFIG_SET('HAVE_SENDFILE'):
1561         conf.fatal('sendfile support not found but it was requested !')
1562     # Check for getcwd allowing a NULL arg.
1563     conf.CHECK_CODE('''
1564 #include <unistd.h>
1565 main() {
1566         char *s = getcwd(NULL,0);
1567         exit(s != NULL ?  0 : 1);
1568 }''', 'GETCWD_TAKES_NULL', addmain=False, execute=True,
1569         msg="getcwd takes a NULL argument")
1570
1571
1572     # UnixWare 7.x has its getspnam in -lgen
1573     conf.CHECK_FUNCS_IN('getspnam', 'gen')
1574     conf.CHECK_FUNCS_IN('getspnam', 'security')
1575     conf.CHECK_FUNCS_IN('getspnam', 'sec')
1576
1577     legacy_quota_libs = ''
1578     if not Options.options.with_quotas == False:
1579         # For quotas on Veritas VxFS filesystems
1580         conf.CHECK_HEADERS('sys/fs/vx_quota.h')
1581         # For sys/quota.h and linux/quota.h
1582         conf.CHECK_HEADERS('sys/quota.h')
1583         # For quotas on BSD systems
1584         conf.CHECK_HEADERS('ufs/ufs/quota.h')
1585         # For quotas on AIX systems
1586         conf.CHECK_HEADERS('jfs/quota.h')
1587         # For quotas on Linux XFS filesystems
1588         if conf.CHECK_HEADERS('xfs/xqm.h'):
1589             conf.DEFINE('HAVE_XFS_QUOTAS', '1')
1590         else:
1591             # For Irix XFS
1592             conf.CHECK_CODE('''
1593                 #include "confdefs.h"
1594                 #ifdef HAVE_SYS_TYPES_H
1595                 #include <sys/types.h>
1596                 #endif
1597                 #ifdef HAVE_ASM_TYPES_H
1598                 #include <asm/types.h>
1599                 #endif
1600                 #include <sys/quota.h>
1601                 int i = Q_XGETQUOTA;''',
1602                 define='HAVE_XFS_QUOTAS',
1603                 msg='for XFS QUOTA in <sys/quota.h>',
1604                 execute=False,
1605                 local_include=False)
1606
1607         # For IRIX like dqb_isoftlimit instead of dqb_fsoftlimit in struc dqblk
1608         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_fsoftlimit', define='HAVE_DQB_FSOFTLIMIT',
1609                                 headers='sys/quota.h')
1610         #darwin style quota bytecount
1611         conf.CHECK_STRUCTURE_MEMBER('struct dqblk', 'dqb_curbytes', define='HAVE_STRUCT_DQBLK_DQB_CURBYTES',
1612                                 headers='sys/quota.h')
1613         conf.CHECK_HEADERS('rpc/types.h rpc/xdr.h', together=True)
1614         if conf.CHECK_HEADERS('rpcsvc/rquota.h', lib='tirpc'):
1615             # Optional structure member
1616             conf.CHECK_STRUCTURE_MEMBER('struct getquota_rslt', 'getquota_rslt_u',
1617                                         define='HAVE_GETQUOTA_RSLT_GETQUOTA_RSLT_U',
1618                                         headers='rpcsvc/rquota.h',
1619                                         lib='tirpc')
1620
1621             # Required function for NFS quota support
1622             conf.CHECK_CODE('''
1623                             clnt_create("", RQUOTAPROG, RQUOTAVERS, "udp");
1624                             ''',
1625                             headers="rpc/rpc.h rpc/types.h rpcsvc/rquota.h rpc/nettype.h rpc/xdr.h",
1626                             define='HAVE_NFS_QUOTAS',
1627                             msg='checking for clnt_create()',
1628                             execute=True,
1629                             local_include=False,
1630                             lib='tirpc')
1631
1632         if (host_os.rfind('linux') > -1):
1633             conf.DEFINE('HAVE_QUOTACTL_LINUX', '1')
1634         elif not conf.CONFIG_SET("HAVE_XFS_QUOTAS"):
1635             if not conf.CHECK_CODE('''
1636                 #define HAVE_QUOTACTL_4A 1
1637                 #define AUTOCONF_TEST 1
1638                 #include "../tests/sysquotas.c"
1639                 ''',
1640                                    cflags=conf.env['WERROR_CFLAGS'],
1641                                    define='HAVE_QUOTACTL_4A',
1642                                    msg='for QUOTACTL_4A: long quotactl(int cmd, char *special, qid_t id, caddr_t addr)',
1643                                    execute=True,
1644                                    addmain=False):
1645
1646                 conf.CHECK_CODE('''
1647                 #define HAVE_QUOTACTL_4B 1
1648                 #define AUTOCONF_TEST 1
1649                 #include "../tests/sysquotas.c"
1650                 ''',
1651                                 cflags=conf.env['WERROR_CFLAGS'],
1652                                 define='HAVE_QUOTACTL_4B',
1653                                 msg='for QUOTACTL_4B:  int quotactl(const char *path, int cmd, int id, char *addr)',
1654                                 execute=True,
1655                                 addmain=False)
1656
1657         if conf.CONFIG_SET('HAVE_QUOTACTL_LINUX') or \
1658            conf.CONFIG_SET('HAVE_QUOTACTL_4A') or \
1659            conf.CONFIG_SET('HAVE_QUOTACTL_4B') or \
1660            conf.CONFIG_SET('HAVE_XFS_QUOTAS'):
1661             conf.DEFINE('HAVE_SYS_QUOTAS', '1')
1662             conf.DEFINE('WITH_QUOTAS', '1')
1663
1664         #
1665         # check if Legacy quota code can be brought in
1666         # if standard interfaces are not supported
1667         #
1668         if not conf.CONFIG_SET('WITH_QUOTAS'):
1669             if host_os.rfind('sunos5') > -1:
1670                 conf.DEFINE('SUNOS5', '1')
1671                 legacy_quota_libs = 'nsl'
1672             conf.CHECK_CODE('''
1673             #define WITH_QUOTAS 1
1674             #define AUTOCONF_TEST 1
1675             #include "../tests/oldquotas.c"
1676             ''',
1677                             cflags=conf.env['WERROR_CFLAGS'],
1678                             define='WITH_QUOTAS',
1679                             lib=legacy_quota_libs,
1680                             msg='Checking whether legacy quota code can be used',
1681                             execute=False,
1682                             addmain=False)
1683             if not conf.CONFIG_SET('WITH_QUOTAS'):
1684                 legacy_quota_libs = ''
1685     conf.env['legacy_quota_libs'] = legacy_quota_libs
1686
1687     if Options.options.with_quotas == True and not conf.CONFIG_SET('WITH_QUOTAS'):
1688         conf.fatal('quota support not found but it was requested !')
1689
1690     conf.CHECK_CODE('(void)unshare(CLONE_FS);',
1691                     headers='sched.h',
1692                     define='HAVE_UNSHARE_CLONE_FS',
1693                     msg='for Linux unshare(CLONE_FS)')
1694
1695     # Check for mallinfo
1696     conf.CHECK_CODE('''
1697     struct mallinfo mi;
1698     int tmp;
1699
1700     mi = mallinfo();
1701     tmp = mi.arena + mi.ordblks + mi.smblks + mi.hblks +
1702           mi.hblkhd + mi.usmblks + mi.fsmblks +  mi.uordblks +
1703           mi.fordblks + mi.keepcost;
1704     return tmp;
1705     ''', 'HAVE_MALLINFO', msg="Checking for mallinfo()", headers='malloc.h')
1706
1707     #
1708     # cluster support (CTDB)
1709     #
1710     if not Options.options.with_cluster_support:
1711         Logs.info("building without cluster support (--without-cluster-support)")
1712         conf.env.with_ctdb = False
1713     else:
1714         Logs.info("building with cluster support")
1715         conf.env.with_ctdb = True
1716         conf.DEFINE('CLUSTER_SUPPORT', 1)
1717
1718     conf.CHECK_CODE('void seekdir(DIR *d, long loc) { return; }',
1719                     'SEEKDIR_RETURNS_VOID',
1720                     headers='sys/types.h dirent.h',
1721                     msg='Checking whether seekdir returns void')
1722
1723     if Options.options.with_profiling_data:
1724         conf.DEFINE('WITH_PROFILE', 1);
1725         conf.CHECK_FUNCS('getrusage', headers="sys/time.h sys/resource.h")
1726
1727     if (conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h linux/fs.h') and
1728         conf.CHECK_DECLS('FS_IOC_GETFLAGS FS_COMPR_FL', headers='linux/fs.h')):
1729             conf.DEFINE('HAVE_LINUX_IOCTL', '1')
1730
1731     conf.env['CFLAGS_CEPHFS'] = "-D_FILE_OFFSET_BITS=64"
1732     if Options.options.libcephfs_dir:
1733         Logs.error('''--with-libcephfs no longer supported, please use compiler
1734                    flags instead, e.g. GCC LIBRARY_PATH and C_INCLUDE_PATH''')
1735         sys.exit(1)
1736
1737     if (Options.options.with_cephfs and
1738         conf.CHECK_HEADERS('cephfs/libcephfs.h', False, False, 'cephfs') and
1739         conf.CHECK_LIB('cephfs', shlib=True)):
1740         if (Options.options.with_acl_support and
1741             conf.CHECK_FUNCS_IN('ceph_statx', 'cephfs',
1742                                 headers='cephfs/libcephfs.h')):
1743             conf.DEFINE('HAVE_CEPH', '1')
1744         else:
1745             Logs.warn('''Ceph support disabled due to --without-acl-support
1746                       or lack of ceph_statx support''')
1747             conf.undefine('HAVE_CEPH')
1748
1749     if Options.options.with_glusterfs:
1750         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 4" --cflags --libs',
1751                        msg='Checking for glusterfs-api >= 4', uselib_store="GFAPI")
1752         conf.CHECK_HEADERS('glusterfs/api/glfs.h', lib='gfapi')
1753         conf.CHECK_LIB('gfapi', shlib=True)
1754
1755         if conf.CONFIG_SET('HAVE_GLUSTERFS_API_GLFS_H'):
1756             if Options.options.with_acl_support:
1757                  conf.DEFINE('HAVE_GLUSTERFS', '1')
1758             else:
1759                 Logs.warn("GlusterFS support disabled due to --without-acl-support")
1760                 conf.undefine('HAVE_GLUSTERFS')
1761         else:
1762             conf.undefine('HAVE_GLUSTERFS')
1763
1764         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 6" --cflags --libs',
1765                        msg='Checking for glusterfs-api >= 6',
1766                        uselib_store="GFAPI_VER_6")
1767         conf.CHECK_CFG(package='glusterfs-api', args='"glusterfs-api >= 7.6" --cflags --libs',
1768                        msg='Checking for glusterfs-api >= 7.6',
1769                        uselib_store="GFAPI_VER_7_6")
1770     else:
1771         conf.SET_TARGET_TYPE('gfapi', 'EMPTY')
1772         conf.undefine('HAVE_GLUSTERFS')
1773
1774     if Options.options.enable_vxfs:
1775         conf.DEFINE('HAVE_VXFS', '1')
1776
1777     if Options.options.with_snapper:
1778         if conf.CHECK_CFG(package='dbus-1', args='--cflags --libs',
1779                       msg='Checking for dbus', uselib_store="DBUS-1"):
1780             if (conf.CHECK_HEADERS('dbus/dbus.h', lib='dbus-1')
1781                                       and conf.CHECK_LIB('dbus-1', shlib=True)):
1782                 conf.DEFINE('HAVE_DBUS', '1')
1783         else:
1784             conf.fatal("vfs_snapper is enabled but prerequisite DBUS libraries "
1785                        "or headers not found. Use --disable-snapper to disable "
1786                        "vfs_snapper support.");
1787
1788     if conf.CHECK_CFG(package='liburing', args='--cflags --libs',
1789                       msg='Checking for liburing package', uselib_store="URING"):
1790         if (conf.CHECK_HEADERS('liburing.h', lib='uring')
1791                                       and conf.CHECK_LIB('uring', shlib=True)):
1792             conf.CHECK_FUNCS_IN('io_uring_ring_dontfork', 'uring',
1793                                 headers='liburing.h')
1794             conf.DEFINE('HAVE_LIBURING', '1')
1795
1796     conf.env.build_regedit = False
1797     if not Options.options.with_regedit == False:
1798         conf.PROCESS_SEPARATE_RULE('system_ncurses')
1799         if conf.CONFIG_SET('HAVE_NCURSES'):
1800             conf.env.build_regedit = True
1801
1802     if conf.env.build_regedit:
1803         Logs.info("building regedit")
1804     else:
1805         if Options.options.with_regedit == False:
1806             Logs.info("not building regedit (--without-regedit)")
1807         elif Options.options.with_regedit == True:
1808             Logs.error("ncurses not available, cannot build regedit")
1809             conf.fatal("ncurses not available, but --with-regedit was specified")
1810         else:
1811             Logs.info("ncurses not available, not building regedit")
1812
1813     if conf.CHECK_HEADERS('ftw.h') and conf.CHECK_FUNCS('nftw'):
1814         conf.env.build_mvxattr = True
1815
1816     conf.env.build_winexe = False
1817     if not Options.options.with_winexe == False:
1818         if conf.CONFIG_SET('HAVE_WINEXE_CC_WIN32') or conf.CONFIG_SET('HAVE_WINEXE_CC_WIN64'):
1819             conf.env.build_winexe = True
1820
1821     if conf.env.build_winexe:
1822         Logs.info("building winexe")
1823     else:
1824         if Options.options.with_winexe == False:
1825             Logs.info("not building winexe (--without-winexe)")
1826         elif Options.options.with_winexe == True:
1827             Logs.error("mingw not available, cannot build winexe")
1828             conf.fatal("mingw not available, but --with-winexe was specified")
1829         else:
1830             Logs.info("mingw not available, not building winexe")
1831
1832     conf.CHECK_FUNCS_IN('DES_pcbc_encrypt', 'crypto')
1833     if Options.options.with_fake_kaserver == True:
1834         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1835         conf.CHECK_HEADERS('afs/param.h afs/stds.h', together=True)
1836         if (conf.CONFIG_SET('HAVE_AFS_PARAM_H') and conf.CONFIG_SET('HAVE_AFS_STDS_H') and conf.CONFIG_SET('HAVE_DES_PCBC_ENCRYPT')):
1837             conf.DEFINE('WITH_FAKE_KASERVER', '1')
1838         else:
1839             conf.fatal('AFS headers not available, but --with-fake-kaserver was specified')
1840
1841     if conf.CHECK_CFG(package='glib-2.0',
1842                       args='--cflags --libs',
1843                       msg='Checking for glib-2.0',
1844                       uselib_store="GLIB-2.0"):
1845         if (conf.CHECK_HEADERS('glib.h', lib='glib-2.0') and conf.CHECK_LIB('glib-2.0', shlib=True)):
1846             conf.DEFINE('HAVE_GLIB', 1)
1847
1848     if conf.CONFIG_SET('HAVE_GLIB'):
1849         conf.DEFINE('WITH_TEVENT_GLIB_GLUE', '1')
1850
1851     conf.env['libtracker']=''
1852     tracker_versions = ['2.0', '1.0', '0.16', '0.14']
1853
1854     for version in tracker_versions:
1855         testlib = 'tracker-sparql-' + version
1856         if conf.CHECK_CFG(package=testlib,
1857                           args='--cflags --libs',
1858                           mandatory=False):
1859             conf.SET_TARGET_TYPE(testlib, 'SYSLIB')
1860             conf.env['libtracker'] = testlib
1861             conf.DEFINE('HAVE_TRACKER', '1')
1862             break
1863
1864     Logs.info("Checking for bison")
1865     bison.configure(conf)
1866     if conf.env['BISON']:
1867         conf.CHECK_COMMAND('%s --version  | head -n1' % conf.env.BISON[0],
1868                            msg='Using bison version',
1869                            define=None,
1870                            on_target=False)
1871
1872     Logs.info("Checking for flex")
1873     conf.find_program('flex', var='FLEX')
1874     if conf.env['FLEX']:
1875         conf.env.FLEXFLAGS = ['-t']
1876         conf.CHECK_COMMAND('%s --version' % conf.env.FLEX[0],
1877                            msg='Using flex version',
1878                            define=None,
1879                            on_target=False)
1880
1881     with_spotlight_tracker_backend = (
1882         conf.CONFIG_SET('HAVE_TRACKER')
1883         and conf.CONFIG_SET('HAVE_GLIB')
1884         and conf.env['BISON']
1885         and conf.env['FLEX']
1886         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1887     )
1888
1889     with_spotlight_es_backend = (
1890         conf.CONFIG_SET('HAVE_JSON_OBJECT')
1891         and conf.env['BISON']
1892         and conf.env['FLEX']
1893         and conf.CONFIG_GET('HAVE_UTF8_NORMALISATION')
1894     )
1895
1896     conf.env.with_spotlight = False
1897     if Options.options.with_spotlight is not False:
1898         backends = ['noindex']
1899
1900         if not conf.env['BISON']:
1901             Logs.warn("Spotlight support requested but bison missing")
1902         if not conf.env['FLEX']:
1903             Logs.warn("Spotlight support requested but flex missing")
1904         if not conf.CONFIG_GET('HAVE_UTF8_NORMALISATION'):
1905             Logs.warn("Missing support for Unicode normalisation. "
1906                       "Try installing icu-dev or libicu-devel.")
1907         if not conf.CONFIG_SET('HAVE_TRACKER'):
1908             Logs.warn('Missing libtracker-sparql development files for Spotlight backend "tracker"')
1909         if not conf.CONFIG_SET('HAVE_GLIB'):
1910             Logs.warn('Missing glib-2.0 development files for Spotlight backend "tracker"')
1911         if not conf.CONFIG_GET('HAVE_JSON_OBJECT'):
1912             Logs.warn('Missing libjansson development files for Spotlight backend "elasticsearch"')
1913
1914         if with_spotlight_tracker_backend:
1915             conf.env.spotlight_backend_tracker = True
1916             backends.append('tracker')
1917             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_TRACKER', '1')
1918
1919         if with_spotlight_es_backend:
1920             conf.env.spotlight_backend_es = True
1921             backends.append('elasticsearch')
1922             conf.DEFINE('HAVE_SPOTLIGHT_BACKEND_ES', '1')
1923
1924         if (Options.options.with_spotlight is True
1925             and not conf.env.spotlight_backend_tracker
1926             and not conf.env.spotlight_backend_es):
1927             conf.fatal("Unmet dependencies for Spotlight backends")
1928
1929         Logs.info("Building with Spotlight support, available backends: %s" % ', '.join(backends))
1930         default_static_modules.extend(TO_LIST('rpc_mdssvc_module'))
1931         conf.DEFINE('WITH_SPOTLIGHT', '1')
1932         conf.env.with_spotlight = True
1933
1934     if not conf.CONFIG_SET('HAVE_RPC_XDR_H'):
1935         conf.CHECK_HEADERS('rpc/xdr.h', lib='tirpc')
1936
1937     if conf.CHECK_FUNCS_IN('nscd_flush_cache', 'nscd', headers='libnscd.h'):
1938         conf.DEFINE('HAVE_NSCD_FLUSH_CACHE', '1')
1939
1940     forced_static_modules.extend(TO_LIST('auth_builtin auth_sam auth_winbind'))
1941     default_static_modules.extend(TO_LIST('''pdb_smbpasswd pdb_tdbsam
1942                                       auth_unix
1943                                       nss_info_template idmap_tdb idmap_passdb
1944                                       idmap_nss'''))
1945
1946     default_shared_modules.extend(TO_LIST('''
1947                                       vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit
1948                                       vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap
1949                                       vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2
1950                                       vfs_readahead vfs_xattr_tdb
1951                                       vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb
1952                                       vfs_preopen vfs_catia
1953                                       vfs_media_harmony vfs_unityed_media vfs_fruit vfs_shell_snap
1954                                       vfs_commit vfs_worm vfs_crossrename vfs_linux_xfs_sgid
1955                                       vfs_time_audit vfs_offline vfs_virusfilter vfs_widelinks
1956                                   '''))
1957     default_shared_modules.extend(TO_LIST('idmap_tdb2 idmap_script'))
1958     # these have broken dependencies
1959     forced_shared_modules.extend(TO_LIST('idmap_autorid idmap_rid idmap_hash'))
1960
1961     if Options.options.developer:
1962         default_static_modules.extend(TO_LIST('charset_weird'))
1963         default_shared_modules.extend(TO_LIST('perfcount_test'))
1964         default_shared_modules.extend(TO_LIST('vfs_skel_opaque vfs_skel_transparent vfs_shadow_copy_test'))
1965         default_shared_modules.extend(TO_LIST('auth_skel pdb_test'))
1966         default_shared_modules.extend(TO_LIST('vfs_fake_dfq'))
1967         default_shared_modules.extend(TO_LIST('gpext_security gpext_registry gpext_scripts'))
1968
1969     if Options.options.enable_selftest or Options.options.developer:
1970         default_shared_modules.extend(TO_LIST('vfs_fake_acls vfs_nfs4acl_xattr'))
1971         default_shared_modules.extend(TO_LIST('vfs_error_inject'))
1972         default_shared_modules.extend(TO_LIST('vfs_delay_inject'))
1973
1974     if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
1975         default_static_modules.extend(TO_LIST('pdb_samba_dsdb auth_samba4 vfs_dfs_samba4'))
1976         default_shared_modules.extend(TO_LIST('vfs_posix_eadb'))
1977
1978     if conf.CONFIG_SET('HAVE_FREEBSD_SUNACL_H'):
1979         default_shared_modules.extend(TO_LIST('vfs_zfsacl'))
1980
1981     if conf.CONFIG_SET('HAVE_DIRFD_DECL'):
1982         default_shared_modules.extend(TO_LIST('vfs_syncops vfs_dirsort'))
1983
1984     if conf.CONFIG_SET('HAVE_STATFS_F_FSID'):
1985         default_shared_modules.extend(TO_LIST('vfs_fileid'))
1986
1987     if (conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_CONTROL') or conf.CONFIG_SET('HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS')):
1988         default_shared_modules.extend(TO_LIST('vfs_aio_fork'))
1989
1990     if conf.CONFIG_SET('HAVE_LIBURING'):
1991         default_shared_modules.extend(TO_LIST('vfs_io_uring'))
1992
1993     if Options.options.with_pthreadpool:
1994         default_shared_modules.extend(TO_LIST('vfs_aio_pthread'))
1995
1996     if conf.CONFIG_SET('HAVE_LDAP'):
1997         default_static_modules.extend(TO_LIST('pdb_ldapsam idmap_ldap'))
1998
1999     if conf.CONFIG_SET('DARWINOS'):
2000         default_static_modules.extend(TO_LIST('charset_macosxfs'))
2001
2002     if conf.CONFIG_SET('HAVE_GPFS'):
2003         default_shared_modules.extend(TO_LIST('vfs_gpfs'))
2004
2005     if (conf.CONFIG_SET('HAVE_LINUX_IOCTL')
2006       and conf.CONFIG_SET('HAVE_BASENAME') and conf.CONFIG_SET('HAVE_DIRNAME')):
2007         default_shared_modules.extend(TO_LIST('vfs_btrfs'))
2008
2009     if conf.CONFIG_SET("HAVE_CEPH"):
2010         default_shared_modules.extend(TO_LIST('vfs_ceph'))
2011         # Unlike vfs_ceph, vfs_ceph_snapshots doesn't depend on libcephfs, so
2012         # can be enabled atop a kernel CephFS share (with vfs_default) in
2013         # addition to vfs_ceph. Still, only enable vfs_ceph_snapshots builds
2014         # if we're building with libcephfs for now.
2015         default_shared_modules.extend(TO_LIST('vfs_ceph_snapshots'))
2016
2017     if conf.CONFIG_SET('HAVE_GLUSTERFS'):
2018         default_shared_modules.extend(TO_LIST('vfs_glusterfs'))
2019
2020     if conf.CONFIG_SET('HAVE_SETMNTENT'):
2021         default_shared_modules.extend(TO_LIST('vfs_glusterfs_fuse'))
2022
2023     if conf.CONFIG_SET('HAVE_VXFS'):
2024         default_shared_modules.extend(TO_LIST('vfs_vxfs'))
2025
2026     if conf.CONFIG_SET('HAVE_DBUS'):
2027         default_shared_modules.extend(TO_LIST('vfs_snapper'))
2028
2029     explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',')
2030     explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',')
2031
2032     def replace_list_item(lst, item, value):
2033         try:
2034             idx = lst.index(item)
2035             lst[idx] = value
2036         except:
2037             pass
2038     # PDB module file name should have the same name as module registers itself
2039     # In Autoconf build we export LDAP passdb module as ldapsam but WAF build
2040     # was always exporting pdb_ldap. In order to support existing packages
2041     # allow referring to pdb_ldapsam as pdb_ldap but use proper name internally.
2042     replace_list_item(explicit_shared_modules, 'pdb_ldap', 'pdb_ldapsam')
2043     replace_list_item(explicit_static_modules, 'pdb_ldap', 'pdb_ldapsam')
2044
2045     final_static_modules = []
2046     final_static_modules.extend(TO_LIST(required_static_modules))
2047     final_shared_modules = []
2048
2049     if '!FORCED' not in explicit_static_modules:
2050         final_static_modules.extend(TO_LIST(forced_static_modules))
2051     if '!FORCED' not in explicit_shared_modules:
2052         final_shared_modules.extend(TO_LIST(forced_shared_modules))
2053     if '!DEFAULT' not in explicit_static_modules:
2054         final_static_modules.extend(TO_LIST(default_static_modules))
2055     if '!DEFAULT' not in explicit_shared_modules:
2056         final_shared_modules.extend(TO_LIST(default_shared_modules))
2057
2058     if 'ALL' in explicit_static_modules:
2059         for m in default_shared_modules:
2060             if m in final_shared_modules:
2061                 final_shared_modules.remove(m)
2062             final_static_modules.append(m)
2063     if 'ALL' in explicit_shared_modules:
2064         for m in default_static_modules:
2065             if m in final_static_modules:
2066                 final_static_modules.remove(m)
2067             final_shared_modules.append(m)
2068
2069     for m in explicit_static_modules:
2070         if m in ['ALL','!DEFAULT','!FORCED']:
2071             continue
2072         if m.startswith('!'):
2073             m = m[1:]
2074             if m in required_static_modules:
2075                 raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2076                                      ' '.join(required_static_modules))
2077             if m in final_static_modules:
2078                 final_static_modules.remove(m)
2079             continue
2080         if m in forced_shared_modules:
2081             raise Errors.WafError('These modules MUST be configured as shared modules: %s' %
2082                                  ' '.join(forced_shared_modules))
2083         if m in final_shared_modules:
2084             final_shared_modules.remove(m)
2085         if m not in final_static_modules:
2086             final_static_modules.append(m)
2087     for m in explicit_shared_modules:
2088         if m in ['ALL','!DEFAULT','!FORCED']:
2089             continue
2090         if m.startswith('!'):
2091             m = m[1:]
2092             if m in final_shared_modules:
2093                 final_shared_modules.remove(m)
2094             continue
2095         if m in required_static_modules:
2096             raise Errors.WafError('These modules are REQUIRED as static modules: %s' %
2097                                  ' '.join(required_static_modules))
2098         if m in forced_static_modules:
2099             raise Errors.WafError('These module MUST be configured as static modules: %s' %
2100                                  ' '.join(forced_static_modules))
2101         if m in final_static_modules:
2102             final_static_modules.remove(m)
2103         if m not in final_shared_modules:
2104             final_shared_modules.append(m)
2105
2106     conf.env['static_modules'] = final_static_modules
2107     conf.env['shared_modules'] = final_shared_modules
2108
2109     conf.DEFINE('STRING_STATIC_MODULES', ' '.join(final_static_modules), quote=True)
2110
2111     static_list = {}
2112     shared_list = {}
2113
2114     prefixes = ['vfs', 'pdb', 'auth', 'nss_info', 'charset', 'idmap', 'gpext', 'perfcount', 'rpc']
2115     conf.env['MODULE_PREFIXES'] = prefixes
2116     for p in prefixes:
2117         for m in final_static_modules:
2118             if m.find(p) == 0:
2119                 if not p in static_list:
2120                     static_list[p] = []
2121                 static_list[p].append(m)
2122         for m in final_shared_modules:
2123             if m.find(p) == 0:
2124                 if not p in shared_list:
2125                     shared_list[p] = []
2126                 shared_list[p].append(m)
2127
2128     for p in prefixes:
2129         static_env = "%s_STATIC" % p.upper()
2130         shared_env = "%s_SHARED" % p.upper()
2131         conf.env[static_env] = []
2132         conf.env[shared_env] = []
2133         if p in static_list:
2134             decl_list = " ".join("extern NTSTATUS %s_init(TALLOC_CTX *mem_ctx); " % entry for entry in static_list[p])
2135             for entry in static_list[p]:
2136                 conf.env[static_env].append('%s' % entry)
2137             conf.DEFINE('static_decl_%s' % p, decl_list)
2138             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{ %s_init((mem_ctx)); }' % '_init((mem_ctx));  '.join(static_list[p]))
2139         else:
2140             conf.DEFINE('static_decl_%s' % p, '')
2141             conf.DEFINE('static_init_%s(mem_ctx)' % p, '{}')
2142         if p in shared_list:
2143             for entry in shared_list[p]:
2144                 conf.DEFINE('%s_init' % entry, 'samba_init_module')
2145                 conf.env[shared_env].append('%s' % entry)
2146         Logs.info("%s: %s" % (static_env, ','.join(conf.env[static_env])))
2147         Logs.info("%s: %s" % (shared_env, ','.join(conf.env[shared_env])))
2148
2149     conf.SAMBA_CONFIG_H('include/config.h')