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