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