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