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